我认为可以公平地说,作为软件开发人员,我们一直在寻找编写较少代码的方法,这些方法可以自动完成或不能自动完成更多工作。 考虑到这一点,作为Spring产品组合的骄傲成员的Spring Boot项目破坏了传统方法,极大地加快了并简化了基于Spring的应用程序的开发。
关于Spring Boot ,还有很多要说的东西 ,关于它如何工作以及如何与大多数(即使不是全部) Spring项目无缝集成的固有细节。 但是它的功能远不止于此,它支持与流行的Java框架进行一流的集成。
在本文中,我们将研究如何将Spring Boot与Apache CXF项目结合使用,以进行快速的REST(ful)Web服务开发。 我们很快就会看到, Spring Boot会处理很多样板,让我们专注于真正有价值的应用程序部分。 希望在本文结尾处,为您的项目采用Spring Boot的好处显而易见。
这样,我们就可以开始开发一个简单的人员管理REST(ful)Web服务 ,并将其包装到熟悉的PeopleRestService JAX-RS资源中:
@Path("/people")
@Component
public class PeopleRestService {
@GET
@Produces({MediaType.APPLICATION_JSON})
public Collection<Person> getPeople() {
return Collections.singletonList(new Person("a@b.com", "John", "Smith"));
}
}
此处添加的内容不多,是非常简单的实现,它返回人员的硬编码集合。 我们可以通过多种方式打包和部署此JAX-RS服务,但可以说最简单的方法是将其托管在嵌入式servlet容器(例如Tomcat , Jetty或Undertow)中 。 随之而来的是例程:容器初始化,配置Spring上下文位置,注册侦听器,……让我们看看Spring Boot如何通过剖析下面的Spring上下文配置来提供帮助。
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = PeopleRestService.class)
public class AppConfig {
@Autowired private PeopleRestService peopleRestService;
@Bean(destroyMethod = "shutdown")
public SpringBus cxf() {
return new SpringBus();
}
@Bean(destroyMethod = "destroy") @DependsOn("cxf")
public Server jaxRsServer() {
final JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setServiceBean(peopleRestService);
factory.setProvider(new JacksonJsonProvider());
factory.setBus(cxf());
factory.setAddress("/");
return factory.create();
}
@Bean
public ServletRegistrationBean cxfServlet() {
final ServletRegistrationBean servletRegistrationBean =
new ServletRegistrationBean(new CXFServlet(), "/api/*");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
}
AppConfig类看起来像一个典型的基于Spring Java的配置,除了这个异常的@EnableAutoConfiguration批注,毫无疑问 ,它来自Spring Boot模块。 在幕后,使用此注释可以进行复杂且智能的猜测,尤其是猜测我们将要运行哪种应用程序以及我们的应用程序可能需要哪种Spring Bean。 有了此配置后,我们只需要为我们的应用程序提供一个运行程序,同时也要具有一些Spring Boot风格:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
}
@SpringBootApplication元注释,并使用SpringApplication初始化我们的Spring上下文,我们有了一个成熟的可运行Java应用程序,可以使用Spring Boot插件从Apache Maven运行该应用程序:
mvn spring-boot:run
JAR并从命令行调用:
mvn package
java -jar target/jax-rs-2.0-cxf-spring-boot-0.0.1-SNAPSHOT.jar
main方法)。 一旦运行了应用程序,就可以确保我们的人员管理REST(ful)Web服务已正确部署并且可以正常运行:
$ curl -i http://localhost:8080/api/people
HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
Server: Jetty(9.3.8.v20160314)
[{"email":"a@b.com","firstName":"John","lastName":"Smith"}]
在这一点上,您可能想知道它是如何工作的? 我们没有在任何地方处理servlet容器,所以Jetty如何满足我们的请求? 事实是,我们只需要包含选择的容器作为依赖项即可,例如使用Apache Maven的pom.xml文件:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.8.v20160314</version>
</dependency>
Spring Boot与@ EnableAutoConfiguration / @ SpringBootApplication一起完成其余工作:它检测到类路径中是否存在Jetty ,得出一个有效的结论,即我们的意图是运行Web应用程序并用必要的内容补充Spring上下文。 这不只是辉煌吗?
如果不涵盖Spring Boot项目的另一个重要功能,那就是不公平的完成:集成测试支持。 在这方面, Spring Boot采用相同的方法,并提供了一些注释,以消除所有我们不得不另外编写的脚手架。 例如:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AppConfig.class)
@WebIntegrationTest(randomPort = true)
public class PeopleRestServiceIntegrationTest {
@Value("${local.server.port}") private int port;
@Before
public void setUp() {
RestAssured.port = port;
}
@Test
public void testListOfPersonsIsBeingReturnedSuccessfuly() {
given()
.when()
.contentType(ContentType.JSON)
.get("/api/people")
.then()
.statusCode(200)
.log()
.ifValidationFails();
}
}
@SpringApplicationConfiguration (请注意,我们在测试中使用的配置与主应用程序相同)和@WebIntegrationTest这两个注解,它们将Web应用程序测试的细节考虑在内并在随机端口上运行嵌入式servlet容器,并且我们已经针对人员管理JAX-RS服务进行了全面的集成测试。 可通过local.server.port环境属性获得运行servlet容器的端口,因此我们可以在测试背景中配置REST保证的端口。 简单容易。
在本文中,我们仅研究了使用Spring Boot来提高JAX-RS项目的开发速度的一种特定用例。 Spring Boot带来了许多琐碎的事情,每个发行版中都添加了越来越多的智能,更不用说与所选IDE的出色集成。 我希望您真的对Spring Boot感到兴奋,并渴望了解更多有关Spring Boot的信息。 值得花费时间和精力。
完整的项目可以在Github上找到 。
翻译自: https://www.javacodegeeks.com/2016/05/laziness-extreme-developing-jax-rs-services-spring-boot.html