Я думаю, было бы справедливо заявить, что мы, как разработчики программного обеспечения, всегда ищем способы написать меньше кода, который делает больше вещей, автоматически или нет. В связи с этим проект Spring Boot , являющийся гордым участником портфолио Spring , нарушил традиционные подходы, резко ускорив и упростив разработку приложений на основе Spring .
О Spring Boot можно многое сказать, о внутренних деталях его работы и его плавной интеграции с большинством, если не со всеми проектами Spring . Но его возможности выходят далеко за рамки этого, поддерживая первоклассную интеграцию с популярными средами Java.
В этой статье мы рассмотрим, как мы можем использовать Spring Boot в сочетании с проектом Apache CXF для быстрой разработки REST (ful) веб-сервисов . Как мы увидим очень скоро, Spring Boot позаботится о большом количестве шаблонов, что позволит нам сосредоточиться на тех частях приложения, которые действительно имеют ценность. Надеемся, что в конце этого поста преимущества использования Spring Boot для ваших проектов станут очевидными.
После этого давайте начнем с разработки простого веб-сервиса REST (ful) для управления персоналом, включенного в привычный ресурс PeopleRestService JAX-RS :
1
2
3
4
5
6
7
8
9
|
@Path ( "/people" ) @Component public class PeopleRestService { @GET @Produces ({MediaType.APPLICATION_JSON}) public Collection<Person> getPeople() { } } |
Добавлять особо нечего, довольно простая реализация, которая возвращает жестко запрограммированную коллекцию людей. Мы можем упаковать и развернуть этот сервис JAX-RS несколькими способами, но, пожалуй, самый простой из них — разместить его во встроенном контейнере сервлетов, таком как Tomcat , Jetty или Undertow . С этим приходит рутина: инициализация контейнера, настройка местоположений контекста Spring , регистрация слушателей,… Давайте посмотрим, как Spring Boot может помочь здесь, рассмотрев конфигурацию контекста Spring ниже.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@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 нам могут понадобиться для нашего приложения. С этой конфигурацией нам просто нужен бегун для нашего приложения, также с небольшим количеством Spring Boot :
1
2
3
4
5
6
|
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(AppConfig. class , args); } } |
Имея мета-аннотацию @SpringBootApplication и используя SpringApplication для инициализации нашего контекста Spring , у нас есть полноценное работающее Java-приложение, которое можно запустить из Apache Maven с помощью плагина Spring Boot :
1
|
mvn spring-boot:run |
Или упакован как один работающий Uber- JAR и вызывается из командной строки:
1
2
|
mvn package java -jar target/jax-rs- 2.0 -cxf-spring-boot- 0.0 . 1 -SNAPSHOT.jar |
И это все, просто пара аннотаций вместе с одной строкой кода ( основной метод). Запустив приложение, мы сможем убедиться, что наш веб-сервис REST (ful) для управления персоналом правильно развернут и полностью функционирует:
1
2
3
4
5
6
7
8
|
$ 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) |
На данный момент вы можете спросить, как это работает? Мы нигде не имели дело с контейнером сервлетов, так почему же Jetty обслуживает наши запросы? По правде говоря, нам нужно только включить наш контейнер выбора в качестве зависимости, например, используя файл Apache Maven pom.xml :
1
2
3
4
5
|
<dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <version> 9.3 . 8 .v20160314</version> </dependency> |
Spring Boot вместе с @ EnableAutoConfiguration / @ SpringBootApplication делает все остальное: он обнаруживает присутствие Jetty в пути к классам, приходит к обоснованному выводу, что мы намерены запустить веб-приложение и дополнить контекст Spring необходимыми элементами. Разве это не просто великолепно?
Было бы несправедливо заканчивать, не освещая еще одну важную особенность проекта Spring Boot : поддержку интеграционного тестирования. В этом отношении Spring Boot использует тот же подход и предоставляет несколько аннотаций, чтобы снять все строительные леса, которые мы должны были бы написать сами, в противном случае. Например:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@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 (которая учитывает специфику тестирования веб-приложения и запускает встроенный контейнер сервлета на случайном порте), и у нас есть полноценный интеграционный тест с нашей службой управления JAX-RS . Порт, на котором работает контейнер сервлета, доступен через свойство среды local.server.port, поэтому мы можем настроить REST-гарантированный в фоновом режиме тестирования. Легко и просто.
В этой статье мы только что рассмотрели один конкретный случай использования Spring Boot для увеличения скорости разработки ваших проектов JAX-RS . С Spring Boot многие вещи становятся очень тривиальными, с каждым разом добавляется все больше и больше интеллекта, не говоря уже об отличной интеграции с выбранной вами IDE. Я надеюсь, что вы действительно взволнованы Spring Boot и хотите узнать больше об этом. Это стоит времени и усилий.
Полный проект доступен на Github .
Ссылка: | Лень в крайности: разработка сервисов JAX-RS с Spring Boot от нашего партнера по JCG Андрея Редько в блоге Андрея Редько . |