Первоначально написал
Джош Лонг в блоге SpringSource.
В этом блоге я хочу посмотреть — и продемонстрировать — некоторые из многих новых функций в Spring Boot 1.2, которые облегчают жизнь тех, кто приходит или использует Java EE.
Стоит отметить, что большая часть этой поддержки была возможна с Spring раньше, конечно, но теперь с Spring Boot 1.2, это так чертовски легко!
Во-первых, вот пример программы с примечаниями после.
package demo; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.jms.annotation.JmsListener; import org.springframework.jms.core.JmsTemplate; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import javax.jms.JMSException; import javax.persistence.*; import javax.transaction.Transactional; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import java.io.Serializable; import java.util.Collection; import java.util.logging.Logger; @SpringBootApplication public class Application { @Named public static class JerseyConfig extends ResourceConfig { public JerseyConfig() { this.register(GreetingEndpoint.class); this.register(JacksonFeature.class); } } @Named @Transactional public static class GreetingService { @Inject private JmsTemplate jmsTemplate; @PersistenceContext private EntityManager entityManager; public void createGreeting(String name, boolean fail) { Greeting greeting = new Greeting(name); this.entityManager.persist(greeting); this.jmsTemplate.convertAndSend("greetings", greeting); if (fail) { throw new RuntimeException("simulated error"); } } public void createGreeting(String name) { this.createGreeting(name, false); } public Collection<Greeting> findAll() { return this.entityManager .createQuery("select g from " + Greeting.class.getName() + " g", Greeting.class) .getResultList(); } public Greeting find(Long id) { return this.entityManager.find(Greeting.class, id); } } @Named @Path("/hello") @Produces({MediaType.APPLICATION_JSON}) public static class GreetingEndpoint { @Inject private GreetingService greetingService; @POST public void post(@QueryParam("name") String name) { this.greetingService.createGreeting(name); } @GET @Path("/{id}") public Greeting get(@PathParam("id") Long id) { return this.greetingService.find(id); } } @Entity public static class Greeting implements Serializable { @Id @GeneratedValue private Long id; @Override public String toString() { return "Greeting{" + "id=" + id + ", message='" + message + '\'' + '}'; } private String message; public String getMessage() { return message; } public Greeting(String name) { this.message = "Hi, " + name + "!"; } Greeting() { } } @Named public static class TestCommandLineRunner { @Inject private GreetingService greetingService; @PostConstruct public void afterPropertiesSet() throws Exception { greetingService.createGreeting("Phil"); greetingService.createGreeting("Dave"); try { greetingService.createGreeting("Josh", true); } catch (RuntimeException re) { Logger.getLogger(Application.class.getName()).info("caught exception..."); } greetingService.findAll().forEach(System.out::println); } } @Named public static class MessageProcessor { @JmsListener(destination = "greetings") public void processGreeting(Greeting greeting) throws JMSException { System.out.println("received message: " + greeting); } } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Остальная часть кода application.properties
и сборка Maven доступны онлайн.
JAX-RS с Джерси
В этом примере демонстрируется интеграция JAX-RS (в данном случае с использованием Jersey 2.x ) в demo.Application.GreetingEndpoint
. Обратите внимание, как удобно, чтобы все это работало! Единственное, что надо утомить, это то, что вам нужно указать ResourceConfig
подкласс, чтобы Джерси знал, какие компоненты нужно зарегистрировать.
Глобальные транзакции с JTA
Он демонстрирует глобальные транзакции (он же XA ) с новой автоматически настраиваемой поддержкой JTA . Для этого мы использовали автономный JTA-провайдер Atomikos . Мы могли бы также легко использовать Битроникс; оба автоматически настраиваются, если вы берете с собой соответствующий стартер. В этом примере в GreetingService
JMS и JPA работа выполняется как часть глобальной транзакции. Мы демонстрируем это, создав 3 транзакции и симулировав откат третьей. Вы должны увидеть распечатанное на консоли, что есть две записи, которые возвращаются из javax.sql.DataSource
источника данных JDBC, и две записи, полученные из встроенного javax.jms.Destination
места назначения JMS .
Встроенный веб-сервер Undertow
В этом примере также используется великолепный встроенный HTTP-сервер Undertow сервера приложений Wildfly (от RedHat) вместо Apache Tomcat (по умолчанию). Использовать Undertow так же просто, как и Jetty или Tomcat — просто исключите org.springframework.boot:spring-boot-starter-tomcat
и добавьте org.springframework.boot:spring-boot-starter-undertow
! Этот вклад возник как сторонний пиар — спасибо Иван Сопов! Это круто
Шансы и Концы
Просто для согласованности в примере также используется JSR 330. JSR 330 описывает набор аннотаций, которые вы можете использовать на проприетарных серверах приложений, таких как WebLogic, а также в переносимом виде в контейнерах внедрения зависимостей, таких как Google Guice или Spring. Я также использую аннотацию JSR 250 (определенную как часть Java EE 5) для демонстрации хуков жизненного цикла.
В этом примере используется встроенная встроенная память Spring Boot H2 в памяти javax.sql.DataSource
и встроенная встроенная память Spring Hot в памяти HornetQjavax.jms.ConnectionFactory
. Если вы хотите подключиться к не внедренным экземплярам, просто определить компоненты, которые будут выбраны вместо этого.
Этот пример также использует новую @SpringBootApplication
аннотацию , которая сочетает в себе @Configuration
, @EnableAutoConfiguration
и @ComponentScan
. Приятно!
развертывание
Хотя я использую множество довольно знакомых API-интерфейсов Java EE, это все еще просто типичный Spring Boot, поэтому по умолчанию вы можете запустить это приложение, используя его java -jar ee.jar
или легко развернув его на процессно-ориентированных платформах как услугах, таких как — Heroku или Cloud Foundry . Если вы хотите развернуть его на отдельном сервере приложений, таком как (например, Apache Tomcat, или Websphere, или что-то еще между ними), легко преобразовать сборку в a .war
и развернуть ее соответственно в любом контейнере Servlet 3.
Если вы развертываете приложение на более классическом сервере приложений, Spring Boot может вместо этого воспользоваться возможностями AS. Например, очень просто использовать связанные с JNDI JMS ConnectionFactory
, JDBC DataSource
или JTA UserTransaction
.
Spring Boot 1.2: выбор и мощь
Лично я бы поставил под сомнение многие из этих API. Вам действительно нужны распределенные многоресурсные транзакции? В современном распределенном мире глобальные менеджеры транзакций считают запахом архитектуры. Вам действительно нужно использовать JAX-RS, когда Spring предлагает более богатый, интегрированный стек на основе MVC Spring, дополненный поддержкой MVC, REST, HATEOAS, OAuth и веб-сокетов? Вполне возможно, что вы делаете, и, как всегда, выбор за вами. Вот почему этот релиз такой классный! Больше силы, больше выбора.
Что-то еще?
На самом деле, много . Есть множество новых функций. Я не мог даже начать покрывать их всех здесь. Так что я не буду пытаться. Проверьте примечания к выпуску для полного совка!
Spring Boot 1.2 быстро приближается к GA, и сейчас очень подходящее время, чтобы попробовать свои силы, пнуть шины , подать проблемы и задать вопросы !