Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's new in Spring 4?

What's new in Spring 4?

Spring 4.1 est sorti en Septembre et les travaux sur Spring 4.2 sont sur le point de commencer. Venez découvrir les nouveautés apportées par Spring 4. Au menu : support de Java 8, support de websocket, simplification de l'infrastructure de messaging, support de JCache (JSR-107), améliorations significatives du container comme le support des types génériques pour l'injection et bien d'autres choses encore.

Venez découvrir comment développer des composants modernes avec un maximum de flexibilité !

Stéphane Nicoll

January 08, 2015
Tweet

More Decks by Stéphane Nicoll

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What’s new in Spring 4? Stéphane Nicoll Spring framework committer Pivotal - @snicoll
  2. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 2 https://github.com/snicoll @snicoll Stéphane Nicoll [email protected]
  3. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Introducing Spring Framework 4 ! Ready for new application architectures • embedded web servers and non-traditional data stores • lightweight messaging and WebSocket-style architectures • best-of-breed and up-to-date infrastructure for each application ! A new baseline • minimum: Java 6+, Servlet 2.5+, JPA 2.0+ • comprehensive support for Java 8 • strongly Servlet 3.0+ oriented, just Servlet 2.5 compatible at runtime • still compatible with WebSphere 7 + JPA 2.0 feature pack and GAE! 3 @snicoll
  4. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring Framework 4 and Java EE 7 ! Broad support for specifications at the EE 7 level • Servlet 3.1, JSR-356 WebSocket • JSR-236 Managed Concurrency • JPA 2.1, Bean Validation 1.1 • JTA 1.2, JMS 2.0 • JCache 1.0 ! Dedicated support for latest server generations • Tomcat 8.0, Jetty 9.2 • GlassFish 4.0.1, WebLogic 12.1.3 • WebSphere Liberty Profile, Undertow / WildFly 4 @snicoll
  5. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ The State of the art: Component 5 @Service @Lazy public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(AccountRepository repo) { ... } @Transactional public BookUpdate updateBook(Addendum addendum) { ... } }
  6. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ The State of the art: Configuration 6 @Configuration @Profile("standalone") @EnableTransactionManagement public class MyBookAdminConfig { @Bean @Scope("session") public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; } ... }
  7. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Comprehensive support for Java 8
  8. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Lambdas with existing Spring APIs 8 @snicoll JdbcTemplate jt = new JdbcTemplate(dataSource); jt.query("SELECT name, age FROM person WHERE dep = ?", ps -> ps.setString(1, "Sales"), (rs, rowNum) -> new Person(rs.getString(1), rs.getInt(2))); jt.query("SELECT name, age FROM person WHERE dep = ?", ps -> { ps.setString(1, "Sales"); }, (rs, rowNum) -> { return new Person(rs.getString(1), rs.getInt(2)); });
  9. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Method reference 9 public List<Person> getPersonList(String department) { JdbcTemplate jt = new JdbcTemplate(dataSource); return jt.query( "SELECT name, age FROM person WHERE dep = ?", ps -> { ps.setString(1, "Sales"); }, this::mapPerson); } private Person mapPerson(ResultSet rs, int rowNum) throws SQLException { return new Person(rs.getString(1), rs.getInt(2)); }
  10. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Declarative Formatting with Java 8 Date-Time (JSR 310) 10 import java.time.*; import javax.validation.constraints.*; import org.springframework.format.annotation.*; public class Customer { // @DateTimeFormat(iso=ISO.DATE) private LocalDate birthDate; @DateTimeFormat(pattern="M/d/yy h:mm") @NotNull @Past private LocalDateTime lastContact; ... }
  11. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Repeatable annotations 11 @Schedules({ @Scheduled(cron="0 0 12 * * *”), @Scheduled(cron="0 0 18 * * *”) }) public void performTempFileCleanup() { ... } @Scheduled(cron="0 0 12 * * ?") @Scheduled(cron="0 0 18 * * ?") public void performTempFileCleanup() { ... }
  12. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Cache abstraction
  13. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Cache abstraction recap 13 public class BookRepository { } @Cacheable("books") public Book findById(String id) { } @Cacheable(value="books", key="T(demo.caching.BookIdResolver).resolveBookId(#isbn)") public Book findById(ISBN isbn) { } @CachePut(value="books", key="#book.id") public Book update(Book book) { } @CacheEvict(value="books") public void delete(String id) { }
  14. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Cache abstraction recap (cont’d) 14 @Configuration @EnableCaching public class ApplicationConfig { @Value("classpath:my-ehcache.xml") private Resource ehCacheConfig; @Bean public CacheManager cacheManager() { return new EhCacheCacheManager(EhCacheManagerUtils .buildCacheManager(ehCacheConfig)); } }
  15. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Class-level customisations 15 @CacheConfig("books") public class BookRepository { @Cacheable public Book findById(String id) { } @Cacheable(key="T(demo.caching.BookIdResolver).resolveBookId(#isbn)") public Book findById(ISBN isbn) { } @CachePut(key="#book.id") public Book update(Book book) { } @CacheEvict public void delete(String id) { } }
  16. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Operation-level customisations 16 @CacheConfig("books") public class BookRepository { @Cacheable public Book findById(String id) { } @Cacheable(keyGenerator="isbnKeyGenerator") public Book findById(ISBN isbn) { } @CachePut(key="#book.id") public Book update(Book book) { } @CacheEvict public void delete(String id) { } }
  17. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JCache (JSR 107) support 17 import javax.cache.annotation.*; @CacheDefaults(cacheName = "books") public class BookRepository { @CacheResult public Book findById(String id) { } @CacheResult(cacheKeyGenerator=IsbnCacheKeyGenerator.class) public Book findById(ISBN isbn) { } @CachePut public void update(String id, @CacheValue Book book) { } @CacheRemove public void delete(String id) { } }
  18. Demo Unless otherwise indicated, these slides are 
 © 2013-2014

    Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Caching abstraction
  19. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Messaging
  20. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Messaging abstraction ! Foundation for messaging-based applications, formerly from the Spring Integration project ! Applied in numerous areas of the framework to provide a very rich programming model independent of the underlying messaging API 20 @snicoll Order order = new Order(…); Message<Order> message = MessageBuilder.withPayload(order) .setHeader("orderType", "sell") .build();
  21. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JMS listener abstraction recap 21 public class OrderMessageHandler { public OrderStatus handleMessage(Order order) { // order processing, return status } } <beans ...> <jms:listener-container message-converter="jmsMessageConverter"> <jms:listener destination="order" ref="orderMessageHandler" method="handleMessage"/> </jms:listener-container> <bean id="orderMessageHandler" class="demo.OrderMessageHandler"/> <bean id="jmsMessageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter"> <property name="targetType" value="TEXT"/> <property name="typeIdPropertyName" value="__type"/> </bean> </beans>
  22. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JMS annotated endpoint 22 @EnableJms @Configuration public class ApplicationConfig { @Bean public JmsListenerContainerFactory<?> jmsListenerContainerFactory( ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(jmsMessageConverter()); return factory; } } @Component public class OrderMessageHandler { @JmsListener(destination = "order") public OrderStatus process(Order order) { // order processing, return status } }
  23. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Flexible method signature 23 @JmsListener(destination = "order") public void processOrder(Order order) { } @JmsListener(destination = "order") public void processOrder(Session session, TextMessage textMessage) { } @JmsListener(destination = "order") public void processOrder(@Valid Order order) { } @JmsListener(destination = "order") public void processOrder(Order order, @Header String orderType) { } @JmsListener(destination = "order") @SendTo("orderStatus") public OrderStatus processOrder(Order order) { }
  24. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Messaging integration ! JmsMessagingTemplate • Similar to JmsTemplate, using o.s.messaging.Message • Exception translation • No JMS api involved at all • Implements common spring-messaging interfaces 24 @snicoll Message<Order> orderMessage = MessageBuilder. withPayload(order).setHeader("orderType", "sell").build(); messagingTemplate.send("order", orderMessage); @JmsListener(destination = "order") @SendTo("orderStatus") public Message<OrderStatus> processOrder(Message<Order> order) { }
  25. Demo Unless otherwise indicated, these slides are 
 © 2013-2014

    Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Messaging abstraction
  26. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ AMQP support ! Equivalent to the JMS support ! Available as from Spring AMQP 1.4 26 @snicoll @Component public class OrderMessageHandler { @RabbitListener(queues = "order") @SendTo("orderStatus") public OrderStatus processOrder(Order order, @Header String orderType) { } }
  27. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Web
  28. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring MVC annotations ! @MVC very popular and evolving through feedback ! Started in 2.5 + REST in 3.0 ! Many refinements in 3.1 and 3.2 ! WebSocket messaging in 4.0 ! Continues to evolve in 4.1 28 @snicoll
  29. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ @Controller ! The central component stereotype in Spring MVC ! Contains @RequestMapping methods ! Supporting methods: @ModelAttribute/@InitBinder/@ExceptionHandler 29 @snicoll @Controller class UserController { @RequestMapping("/user") @ResponseBody public User getUser() { return new User("eric", "7!#H2"); } }
  30. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ @RestController ! Another component stereotype ! Meta-annotated with @Controller + @ResponseBody ! @ResponseBody “inherited” on method level 30 @snicoll @RestController class UserController { @RequestMapping("/user") public User getUser() { return new User("eric", "7!#H2"); } }
  31. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ @ControllerAdvice ! Auto-detected, just declare it as a bean.“Global” supporting methods:
 @ExceptionHandler, @ModelAttribute, @InitBinder ! Fine-grained control
 @ControllerAdvice(basePackageClasses=MyController.class) 31 @snicoll @ControllerAdvice class GlobalControllerExceptionHandler { @ResponseStatus(HttpStatus.CONFLICT) @ExceptionHandler(DataIntegrityViolationException.class) public void handleConflict() { }
 }
  32. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Jackson @JsonView support 32 @snicoll interface PublicView {}; class User { 
 @JsonView(PublicView.class) private String username
 private String password; ... 
 } @RestController class UserController { @RequestMapping("/user") @JsonView(PublicView.class) public User getUser() { return new User("eric", "7!#H2"); } } {"username": "eric"} https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring
  33. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ WebSocket support ! Introduced in 4.0 ! Support JSR 356 compliant runtimes (and more …) ! Transparent SockJS layer ! fall back on HTTP streaming or long polling ! wide range of browser versions ! Higher-level STOMP messaging
 enables @Controller-style programming model 33 @snicoll
  34. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ STOMP on WebSocket 34 @Controller public class MyStompController { @SubscribeMapping("/positions") public List<PortfolioPosition> getPortfolios(Principal user) { ... } @MessageMapping("/trade") public void executeTrade(Trade trade, Principal user) { ... } }
  35. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Messaging Abstraction with JMS, AMQP, STOMP 35 @JmsListener(destination = "order") @SendTo("orderStatus") public Message<OrderStatus> processOrder(Message<Order> order) { } @RabbitListener(queues = "order") @SendTo("orderStatus") public Message<OrderStatus> processOrder(Message<Order> order) { } @MessageMapping("/order") @SendTo("/orderStatus") public Message<OrderStatus> processOrder(Message<Order> order) { }
  36. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Container improvements
  37. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Generics-based injection matching 37 @snicoll @Bean public MyRepository<Account> myAccountRepository() {} @Bean public MyRepository<Product> myProductRepository() {} @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(MyRepository<Account> repo) { ... } }
  38. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Ordered collection injection 38 @Bean @Order(1) public MyRepository<Account> myAccountRepositoryX() { ... } @Bean @Order(2) public MyRepository<Account> myAccountRepositoryY() { ... } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(List<MyRepository<Account>> repos) { ... } }
  39. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Lazy injection points 39 @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(@Lazy MyRepository<Account> repo) { // 'repo' will be a lazy-initializing proxy } } @Bean @Lazy public MyRepository<Account> myAccountRepository() { return new MyAccountRepositoryImpl(); }
  40. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Optional injection points (Java 8) 40 @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(Optional<MyRepository<Account>> repo) { } }
  41. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What’s next? ! Spring Framework 4.2 - Q2 2015 • @Bean on abstract and default methods • Annotation-based application events • Rich support for CORS and declarative HTTP caching • First-class support for Server-Sent Events in Spring MVC • Data binding and conversion for JSR-354 Money & Currency • Hibernate ORM 5.0 and explicit support for Hibernate OGM 41 @snicoll
  42. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ References ! https://spring.io/ • https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring • https://spring.io/blog/2014/07/28/spring-framework-4-1-spring-mvc-improvements • https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources • https://spring.io/blog/2014/04/30/spring-4-1-s-upcoming-jms-improvements • https://spring.io/blog/2014/04/14/cache-abstraction-jcache-jsr-107-annotations-support ! https://projects.spring.io/spring-framework/ ! https://docs.spring.io/spring/docs/current/spring-framework-reference/ ! https://start.spring.io 42 @snicoll
  43. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thanks!