Статьи

«Хорошая» поддержка Java EE в Spring Boot 1.2


Первоначально написал 
Джош Лонг   в блоге 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 доступны онлайн.

Jersey 2.x ) в demo.Application.GreetingEndpoint. Обратите внимание, как удобно, чтобы все это работало! Единственное, что надо утомить, это то, что вам нужно указать  ResourceConfig подкласс, чтобы Джерси знал, какие компоненты нужно зарегистрировать.

новой автоматически настраиваемой поддержкой JTA . Для этого мы использовали   автономный JTA-провайдер Atomikos . Мы могли бы также легко использовать Битроникс; оба автоматически настраиваются, если вы берете с собой соответствующий стартер. В этом примере в  GreetingServiceJMS и JPA работа выполняется как часть глобальной транзакции. Мы демонстрируем это, создав 3 транзакции и симулировав откат третьей. Вы должны увидеть распечатанное на консоли, что есть две записи, которые возвращаются из javax.sql.DataSource источника данных JDBC, и две записи, полученные из встроенного javax.jms.Destination места назначения JMS  .

встроенный HTTP-сервер Undertow сервера приложений Wildfly (от RedHat)   вместо Apache Tomcat (по умолчанию). Использовать Undertow так же просто, как и Jetty или Tomcat — просто исключите  org.springframework.boot:spring-boot-starter-tomcat и добавьте  org.springframework.boot:spring-boot-starter-undertow! Этот вклад возник как сторонний пиар — спасибо Иван Сопов! Это круто

H2 в памяти  javax.sql.DataSourceи встроенная встроенная память Spring Hot  в памяти HornetQjavax.jms.ConnectionFactory . Если вы хотите подключиться к не внедренным экземплярам, ​​просто определить компоненты, которые будут выбраны вместо этого.

Этот пример  также  использует новую  @SpringBootApplication аннотацию , которая сочетает в себе @Configuration@EnableAutoConfiguration и  @ComponentScan. Приятно!

платформах как услугах,  таких как — Heroku или  Cloud Foundry . Если вы хотите развернуть его на отдельном сервере приложений, таком как (например, Apache Tomcat, или Websphere, или что-то еще между ними), легко преобразовать сборку в a  .war и развернуть ее соответственно в любом контейнере Servlet 3.

Если вы развертываете приложение на более классическом сервере приложений, Spring Boot может вместо этого воспользоваться возможностями AS. Например, очень просто использовать связанные с JNDI  JMS ConnectionFactoryJDBC DataSource  или  JTA UserTransaction .

примечания  к выпуску для полного совка!

Spring Boot 1.2 быстро приближается к GA, и сейчас очень подходящее время, чтобы  попробовать свои силы, пнуть шиныподать проблемы  и  задать вопросы !