Первоначально написал
Джош Лонг в блоге 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 . Мы могли бы также легко использовать Битроникс; оба автоматически настраиваются, если вы берете с собой соответствующий стартер. В этом примере в GreetingServiceJMS и 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, и сейчас очень подходящее время, чтобы попробовать свои силы, пнуть шины , подать проблемы и задать вопросы !