Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Modern Java Component Design with Spring Framework 4.3

2,720 views

Published on

SpringOne Platform 2016
Speaker: Juergen Hoeller; Spring Framework Lead, Pivotal

Spring's programming and configuration model has a strong design philosophy with respect to application components and configuration artifacts. Spring's annotation-based component story is fine-tuned for source code readability as well as consistency across an entire application's codebase. This session presents selected Spring Framework 4 component model highlights, with a focus on the current Spring Framework 4.3 and a selection of Java 8 enabled features, illustrated with many code examples and noteworthy design considerations.

Published in: Technology

Modern Java Component Design with Spring Framework 4.3

  1. 1. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Modern Java Component Design with Spring Framework 4.3 Juergen Hoeller @springjuergen
  2. 2. Unless otherwise indicated, these slides are © 2013-2016 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 Classes 2 @Service @Lazy public class MyBookAdminService implements BookAdminService { // @Autowired public MyBookAdminService(AccountRepository repo) { ... } @Transactional public BookUpdate updateBook(Addendum addendum) { ... } }
  3. 3. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Composable Annotations 3 @Service @Scope("session") @Primary @Transactional(rollbackFor=Exception.class) @Retention(RetentionPolicy.RUNTIME) public @interface MyService {} @MyService public class MyBookAdminService { ... }
  4. 4. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Composable Annotations with Overridable Attributes 4 @Scope(scopeName="session") @Retention(RetentionPolicy.RUNTIME) public @interface MySessionScoped { @AliasFor(annotation=Scope.class, attribute="proxyMode") ScopedProxyMode mode() default ScopedProxyMode.NO; } @Transactional(rollbackFor=Exception.class) @Retention(RetentionPolicy.RUNTIME) public @interface MyTransactional { @AliasFor(annotation=Transactional.class) boolean readOnly(); }
  5. 5. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Convenient Scoping Annotations (out of the box) 5 Web (as of 4.3) @RequestScope @SessionScope @ApplicationScope Elsewhere @RefreshScope @JobScope @StepScope
  6. 6. Unless otherwise indicated, these slides are © 2013-2016 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 Classes 6 @Configuration @Profile("standalone") @EnableTransactionManagement public class MyBookAdminConfig { @Bean public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; } @Bean public DataSource bookAdminDataSource() { ... } }
  7. 7. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration Classes with Autowired Bean Methods 7 @Configuration @Profile("standalone") @EnableTransactionManagement public class MyBookAdminConfig { @Bean public BookAdminService myBookAdminService( DataSource bookAdminDataSource) { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource); return service; } }
  8. 8. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration Classes with Autowired Constructors 8 @Configuration public class MyBookAdminConfig { private final DataSource bookAdminDataSource; // @Autowired public MyBookAdminService(DataSource bookAdminDataSource) { this.bookAdminDataSource = bookAdminDataSource; } @Bean public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(this.bookAdminDataSource); return service; } }
  9. 9. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration Classes with Base Classes 9 @Configuration public class MyApplicationConfig extends MyBookAdminConfig { ... } public class MyBookAdminConfig { @Bean public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; } }
  10. 10. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Configuration Classes with Java 8 Default Methods 10 @Configuration public class MyApplicationConfig implements MyBookAdminConfig { ... } public interface MyBookAdminConfig { @Bean default BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; } }
  11. 11. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Generics-based Injection Matching 11 @Bean public MyRepository<Account> myAccountRepository() { ... } @Bean public MyRepository<Product> myProductRepository() { ... } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(MyRepository<Account> repo) { // specific match, even with other MyRepository beans around } }
  12. 12. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Ordered Collection Injection 12 @Bean @Order(2) public MyRepository<Account> myAccountRepositoryX() { ... } @Bean @Order(1) public MyRepository<Account> myAccountRepositoryY() { ... } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(List<MyRepository<Account>> repos) { // 'repos' List with 2 entries: repository Y first, then X } }
  13. 13. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Injection of Collection Beans 13 @Bean public List<Account> myAccountList() { ... } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(List<Account> repos) { // if no raw Account beans found, looking for a // bean which is a List of Account itself } }
  14. 14. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Lazy Injection Points 14 @Bean @Lazy public MyRepository<Account> myAccountRepository() { return new MyAccountRepositoryImpl(); } @Service public class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(@Lazy MyRepository<Account> repo) { // 'repo' will be a lazy-initializing proxy } }
  15. 15. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Component Declarations with JSR-250 & JSR-330 15 import javax.annotation.*; import javax.inject.*; @ManagedBean public class MyBookAdminService implements BookAdminService { @Inject public MyBookAdminService(Provider<MyRepository<Account>> repo){ // 'repo' will be a lazy handle, allowing for .get() access } @PreDestroy public void shutdown() { ... } }
  16. 16. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Optional Injection Points on Java 8 16 import java.util.*; import javax.annotation.*; import javax.inject.*; @ManagedBean public class MyBookAdminService implements BookAdminService { @Inject public MyBookAdminService(Optional<MyRepository<Account>> repo){ if (repo.isPresent()) { ... } } @PreDestroy public void shutdown() { ... } }
  17. 17. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Annotated MVC Controllers 17 @Controller @CrossOrigin public class MyRestController { @RequestMapping(path="/books/{id}", method=GET) public Book findBook(@PathVariable long id) { return this.bookAdminService.findBook(id); } @RequestMapping(path="/books/new", method=POST) public void newBook(@Valid Book book) { this.bookAdminService.storeBook(book); } }
  18. 18. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Precomposed Annotations for MVC Controllers 18 @RestController @CrossOrigin public class MyRestController { @GetMapping("/books/{id}") public Book findBook(@PathVariable long id) { return this.bookAdminService.findBook(id); } @PostMapping("/books/new") public void newBook(@Valid Book book) { this.bookAdminService.storeBook(book); } }
  19. 19. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ STOMP on WebSocket 19 @Controller public class MyStompController { @SubscribeMapping("/positions") public List<PortfolioPosition> getPortfolios(Principal user) { ... } @MessageMapping("/trade") public void executeTrade(Trade trade, Principal user) { ... } }
  20. 20. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Annotated JMS Endpoints 20 @JmsListener(destination="order") public OrderStatus processOrder(Order order) { ... } @JmsListener(id="orderListener", containerFactory="myJmsFactory", destination="order", selector="type='sell'", concurrency="2-10") @SendTo("orderStatus") public OrderStatus processOrder(Order order, @Header String type) { ... }
  21. 21. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Annotated Event Listeners 21 @EventListener public void processEvent(MyApplicationEvent event) { ... } @EventListener public void processEvent(String payload) { ... } @EventListener(condition="#payload.startsWith('OK')") public void processEvent(String payload) { ... }
  22. 22. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Declarative Cache Interaction 22 @CacheConfig("books") public class BookRepository { @Cacheable(sync=true) public Book findById(String id) { } @CachePut(key="#book.id") public void updateBook(Book book) { } @CacheEvict public void delete(String id) { } }
  23. 23. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JCache (JSR-107) Support 23 import javax.cache.annotation.*; @CacheDefaults(cacheName="books") public class BookRepository { @CacheResult public Book findById(String id) { } @CachePut public void updateBook(String id, @CacheValue Book book) { } @CacheRemove public void delete(String id) { } }
  24. 24. Unless otherwise indicated, these slides are © 2013-2016 Pivotal Software, Inc. and licensed under a Creative Commons Attribution- NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Learn More. Stay Connected. Current: Spring Framework 4.3.2 (July 28th, 2016) Check out Spring Boot 1.4, based on Spring Framework 4.3! @springcentral spring.io/blog @pivotal pivotal.io/blog @pivotalcf http://engineering.pivotal.io @piv

×