Modern Component Design with Spring

25
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Modern Component Design with Spring Juergen Hoeller

description

Speaker: Juergen Hoeller In recent years, the Spring Framework focuses on flexible and powerful Java-based configuration. This talk presents Spring as an annotation-oriented application framework, illustrating the rich set of features that Spring has to offer for modern component design. General component model trends will be discussed along with selected Spring feature highlights, such as standardized annotations for dependency injection, stereotypes, and declarative services such as validation and scheduling.

Transcript of Modern Component Design with Spring

Page 1: Modern Component Design with Spring

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Modern Component Design with Spring

Juergen Hoeller

Page 2: Modern Component Design with Spring

Overview: Spring Component Model Themes● Powerful annotated component model● Custom annotations through composition● Configuration classes and factory methods● Spring Expression Language● Flexible MVC/REST controller style● Declarative validation and formatting● Declarative scheduling and caching

Page 3: Modern Component Design with Spring

Bootstrapping Your Annotated Components● Typical: XML bean definition file

– <context:component-scan base-package=”com.myapp”/>– @Component / @Repository / @Service / @Configuration stereotype– compare: JPA persistence.xml with @Entity classes

● Alternative: AnnotationConfigApplicationContext– scan(basePackage)– register(componentClass)– register(configurationClass)

Page 4: Modern Component Design with Spring

A Typical Annotated Component@Servicepublic class MyBookAdminService implements BookAdminService { @Autowired public MyBookAdminService(AccountRepository ar) { ... }

@Transactional public BookUpdate updateBook(Addendum addendum) { ... }}

Page 5: Modern Component Design with Spring

A More Specific Annotated Component@Service@Scope("session")@Primarypublic class MyBookAdminService implements BookAdminService { @Autowired @Qualifier("production") public MyBookAdminService(@Lazy AccountRepository ar) { ... }

@Transactional(readOnly=false, timeout=10) public BookUpdate updateBook(Addendum addendum) { ... }}

Page 6: Modern Component Design with Spring

Composable Stereotype Model@Service@Scope("session")@Primary@Transactional(rollbackFor=Exception.class)@Retention(RetentionPolicy.RUNTIME)public @interface MyService {}

@MyServicepublic class MyBookAdminService { ...}

Page 7: Modern Component Design with Spring

Custom Scoping Annotations@Scope(value="session", proxyMode=ScopedProxyMode.INTERFACES)@Retention(RetentionPolicy.RUNTIME)public @interface MySessionScoped {}

@Scope(value="session")@Retention(RetentionPolicy.RUNTIME)public @interface MySessionScoped { ScopedProxyMode proxyMode() default ScopedProxyMode.NO;}

Page 8: Modern Component Design with Spring

Custom Transaction Annotations@Transactional(readOnly=false, timeout=10)@Retention(RetentionPolicy.RUNTIME)public @interface MyTransactional {}

@Transactional(rollbackFor=Exception.class)@Retention(RetentionPolicy.RUNTIME)public @interface MyTransactional { boolean readOnly();}

Page 9: Modern Component Design with Spring

Annotated Factory Methods@Bean@Scope("session")@Primarypublic BookAdminService bookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(…); return service;}

@Beanpublic BookAdminService bookAdminService() { return MyServiceFactory.createBookAdminService();}

Page 10: Modern Component Design with Spring

Configuration Classes@Configurationpublic class MyBookAdminConfig { @Bean public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; }

@Bean public DataSource bookAdminDataSource() { ... }}

Page 11: Modern Component Design with Spring

Configuration with Profile and Enable*@Configuration@Profile("standalone")@EnableTransactionManagementpublic class MyBookAdminConfig { @Bean public BookAdminService myBookAdminService() { MyBookAdminService service = new MyBookAdminService(); service.setDataSource(bookAdminDataSource()); return service; }

...}

Page 12: Modern Component Design with Spring

EL in Component Annotations@Repositorypublic class BookTestDatabase { @Value("#{systemProperties.databaseName}") public void setDatabaseName(String dbName) { ... }

@Value("#{strategyBean.databaseKeyGenerator}") public void setKeyGenerator(KeyGenerator kg) { ... }

...}

Page 13: Modern Component Design with Spring

Composable Annotations Revisited@Bean@Scope("session")@Primary@Retention(RetentionPolicy.RUNTIME)public @interface MyBean {}@Autowired@Qualifier("production")@Retention(RetentionPolicy.RUNTIME)public @interface MyAutowired {}@Value("#{systemProperties.databaseName}")@Retention(RetentionPolicy.RUNTIME)public @interface MyDatabaseName {}

Page 14: Modern Component Design with Spring

Standardized Annotations@ManagedBean@MySessionScopedpublic class MyBookAdminService implements BookAdminService { @Inject @Named("production") public MyBookAdminService(Provider<AccountRepository> ar) { ... }

@Transactional public BookUpdate updateBook(Addendum addendum) { ... }}

Page 15: Modern Component Design with Spring

JSR-330 and Co● @javax.inject.Inject is part of JSR-330

– "Dependency Injection for Java"– also defines @Scope, @Qualifier, @Named, and Provider interface

● @javax.transaction.Transactional is part of JTA 1.2 (EE 7)– finally a direct, independent equivalent of Spring's @Transactional – previously: just EJB 3.0's @javax.ejb.TransactionAttribute

● @javax.annotation.ManagedBean is part of JSR-250 v1.1– can be detected through classpath scanning

Page 16: Modern Component Design with Spring

JPA Support with Spring Transactions@Repositorypublic class MyAccountRepository { @PersistenceContext private EntityManager em; @Transactional public void storeAccount(Account account) { this.em.merge(account); }}

Page 17: Modern Component Design with Spring

Standardized vs. Spring-specific APIs● In general, we recommend the use of JSR-330 for DI

– JSR-330 @Inject is almost as capable as Spring's @Autowired– can mix and match with Spring's @Value, @Lazy, etc

● We also recommend the use of JPA 2.x– sufficiently expressive for many purposes now– can unwrap down to e.g. a Hibernate Session from a JPA EntityManager

● However, prefer Spring's stereotype and scoping model– composability is incredibly powerful

Page 18: Modern Component Design with Spring

Annotated MVC Controllers@Controllerpublic class MyMvcController { @RequestMapping(value = "/books/{id}", method = GET) public Book findBook(@PathVariable("id") long id) { return this.bookAdminService.findBook(id); }

@RequestMapping("/books/new") public void newBook(Book book) { this.bookAdminService.storeBook(book); }}

Page 19: Modern Component Design with Spring

Portlet MVC Controller@Controller@RequestMapping("EDIT")public class MyPortletController { @ActionMapping("delete") public void removeBook(@RequestParam("book") String bookId) { this.myService.deleteBook(bookId); }

@EventMapping("BookUpdate") public void updateBook(BookUpdateEvent bookUpdate) { this.myService.updateBook(…); }}

Page 20: Modern Component Design with Spring

STOMP on WebSocket@Controllerpublic class MyStompController { @SubscribeEvent("/positions") public List<PortfolioPosition> getPortfolios(Principal user) { ... }

@MessageMapping(value="/trade") public void executeTrade(Trade trade, Principal user) { ... }}

Page 21: Modern Component Design with Spring

Declarative Model Validationpublic class Book { @NotNull @Past private Date releaseDate;}

@RequestMapping("/books/new")public void newBook(@Valid Book book, BindingResult br) { ...}

Page 22: Modern Component Design with Spring

Declarative Formattingpublic class Book { @NotNull @Past @DateTimeFormat(iso=ISO.DATE) private Date releaseDate;}

public class Book { @DateTimeFormat(iso=ISO.DATE) private LocalDate releaseDate;}

Page 23: Modern Component Design with Spring

Declarative Scheduling@Asyncpublic void sendEmailNotifications() { ...}

@Asyncpublic Future<?> sendEmailNotificationsWithFuture() { return new AsyncResult(...);}

@Scheduled(cron = "0 0 12 * * ?")public void performTempFileCleanup() { ...}

Page 24: Modern Component Design with Spring

Declarative Caching@Cacheablepublic Owner loadOwner(int id) { ...}

@Cacheable(condition="name.length < 10")public Owner loadOwner(String name) { ...}

@CacheEvictpublic void deleteOwner(int id) { ...}

Page 25: Modern Component Design with Spring

Once Again: Spring Component Model Themes● Powerful annotated component model● Custom annotations through composition● Configuration classes and factory methods● Spring Expression Language● Flexible MVC/REST controller style● Declarative validation and formatting● Declarative scheduling and caching