Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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]

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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) { ... } }

Slide 6

Slide 6 text

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; } ... }

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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)); });

Slide 9

Slide 9 text

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 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)); }

Slide 10

Slide 10 text

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; ... }

Slide 11

Slide 11 text

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() { ... }

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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) { }

Slide 14

Slide 14 text

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)); } }

Slide 15

Slide 15 text

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) { } }

Slide 16

Slide 16 text

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) { } }

Slide 17

Slide 17 text

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) { } }

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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 message = MessageBuilder.withPayload(order) .setHeader("orderType", "sell") .build();

Slide 21

Slide 21 text

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 } }

Slide 22

Slide 22 text

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 } }

Slide 23

Slide 23 text

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) { }

Slide 24

Slide 24 text

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 orderMessage = MessageBuilder. withPayload(order).setHeader("orderType", "sell").build(); messagingTemplate.send("order", orderMessage); @JmsListener(destination = "order") @SendTo("orderStatus") public Message processOrder(Message order) { }

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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) { } }

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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"); } }

Slide 30

Slide 30 text

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"); } }

Slide 31

Slide 31 text

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() { }
 }

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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 getPortfolios(Principal user) { ... } @MessageMapping("/trade") public void executeTrade(Trade trade, Principal user) { ... } }

Slide 35

Slide 35 text

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 processOrder(Message order) { } @RabbitListener(queues = "order") @SendTo("orderStatus") public Message processOrder(Message order) { } @MessageMapping("/order") @SendTo("/orderStatus") public Message processOrder(Message order) { }

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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 myAccountRepository() {} @Bean public MyRepository myProductRepository() {} @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(MyRepository repo) { ... } }

Slide 38

Slide 38 text

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 myAccountRepositoryX() { ... } @Bean @Order(2) public MyRepository myAccountRepositoryY() { ... } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(List> repos) { ... } }

Slide 39

Slide 39 text

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 repo) { // 'repo' will be a lazy-initializing proxy } } @Bean @Lazy public MyRepository myAccountRepository() { return new MyAccountRepositoryImpl(); }

Slide 40

Slide 40 text

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> repo) { } }

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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!