49
© Zenika 2011 Spring 3.1 1 Spring 3.1

Spring 3.1

Embed Size (px)

Citation preview

Page 1: Spring 3.1

© Zenika 2011 Spring 3.1 1

Spring 3.1

Page 2: Spring 3.1

© Zenika 2011 Spring 3.1 2

Speaker's qualificationsSpeaker's qualifications

• Arnaud Cogoluègnes• Consultant with Zenika• Has been using Spring since 2005• SpringSource certified trainer• Co-author:

• Spring par la pratique, 2nd edition• Spring Dynamic Modules in Action• Spring Batch in Action

Page 3: Spring 3.1

© Zenika 2011 Spring 3.1 3

AgendaAgenda

• History• Environment• Java configuration• Spring JPA• Cache abstraction• Spring MVC improvements

Page 4: Spring 3.1

© Zenika 2011 Spring 3.1 4

HistoryHistory

• v. 0.9 : june 2003 (foundations)• v. 1.0 : march 2004• v. 1.1 : september 2004• v. 1.2 : may 2005• v. 2.0 : october 2006 (XML namespaces)• v. 2.5 : november 2007 (annotations)• v. 3.0 : décember 2009 (Java config, SpEL, REST)

Page 5: Spring 3.1

© Zenika 2011 Spring 3.1 5

Environment

EnvironmentEnvironment

• Inside the application context

Property SourceProperty Source

ProfileProfile

Page 6: Spring 3.1

© Zenika 2011 Spring 3.1 6

db.driver=org.h2.driverdb.url=jdbc:h2:mem:db1db.user=sadb.password=

Environment / Property SourceEnvironment / Property Source

• Do you know this?

<context:property-placeholder location="database.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${db.driver}" /> <property name="url" value="jdbc:${db.url}" /> <property name="username" value="${db.user}" /> <property name="password" value="${db.password}" /></bean>

database.properties

Page 7: Spring 3.1

© Zenika 2011 Spring 3.1 7

db.driver=org.h2.driverdb.url=jdbc:h2:mem:db1db.user=sadb.password=

Environment / Property SourceEnvironment / Property Source

• Spring 3.1 introduces an abstraction for property sources• But what is a PropertySource anyway?

Property Source =

Page 8: Spring 3.1

© Zenika 2011 Spring 3.1 8

Environment / PropertySourceEnvironment / PropertySource

• Where do PropertySources come from?

ResourcePropertySource

Properties files

System and environmentvariablesProperties

PropertySource

JndiPropertySource

JNDI ServletContext/ConfigPropertySource

Servlet context and config

Page 9: Spring 3.1

© Zenika 2011 Spring 3.1 9

Environment / Property SourceEnvironment / Property Source

• How to refer to PropertySource?

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClass" value="${db.driver}"/> <property name="jdbcUrl" value="${db.url}"/> <property name="username" value="${db.user}"/> <property name="password" value="${db.password}"/></bean>

Page 10: Spring 3.1

© Zenika 2011 Spring 3.1 10

Environment / Property SourceEnvironment / Property Source

• How to refer to PropertySource?

@Configurationpublic class DatabaseConfiguration {

@Value("${db.driver}") private String driver; @Value("${db.url}") private String url; @Value("${db.user}") private String user; @Value("${db.password}") private String password;

@Bean public DataSource dataSource() { // creates DataSource return dataSource; }

}

Page 11: Spring 3.1

© Zenika 2011 Spring 3.1 11

Environment / PropertySourceEnvironment / PropertySource

• How to define a PropertySource ?

<context:property-placeholder location="classpath:application.properties" />

Page 12: Spring 3.1

© Zenika 2011 Spring 3.1 12

Environment / PropertySourceEnvironment / PropertySource

• How to define a PropertySource ?

<context:property-placeholder properties-ref="applicationProperties" />

<util:properties id="applicationProperties"> <prop key="db.driver">org.h2.Driver</prop> <prop key="db.url">jdbc:h2:mem:db1</prop> <prop key="db.user">sa</prop> <prop key="db.password"></prop></util:properties>

Page 13: Spring 3.1

© Zenika 2011 Spring 3.1 13

Environment / PropertySourceEnvironment / PropertySource

• How to define a PropertySource ?

<context-param> <param-name>contextInitializerClasses</param-name> <param-value>com.zenika.SomeInitializer</param-value></context-param>

public class SomeInitializer implements ApplicationContextInitializer <ConfigurableApplicationContext> {

public void initialize( ConfigurableApplicationContext ctx) { PropertySource ps = ... ctx.getEnvironment().getPropertySources().addFirst(ps); }

}

Page 14: Spring 3.1

© Zenika 2011 Spring 3.1 14

Environment / PropertySourceEnvironment / PropertySource

• Unified way to deal with properties• More flexible than simple property placeholder

• Configurable programmatically, useful for test configs

• Part of the new Environment abstraction

Page 15: Spring 3.1

© Zenika 2011 Spring 3.1 15

Environment / ProfileEnvironment / Profile

Environment

Property SourceProperty Source

ProfileProfile

Page 16: Spring 3.1

© Zenika 2011 Spring 3.1 16

Environment / ProfileEnvironment / Profile

"dev" profile

Service

Datasource

Repository

"prod" profile

Datasource

Application Context

Page 17: Spring 3.1

© Zenika 2011 Spring 3.1 17

Environment / ProfileEnvironment / Profile

• Different beans for different environments

<bean class="com.zenika.ContactDao"> <constructor-arg ref="dataSource" /></bean>

<beans profile="test"> <jdbc:embedded-database id="dataSource" type="H2" /></beans>

<beans profile="prod"> <jee:jndi-lookup id="ds" jndi-name="java:comp/env/jdbc/ds" /></beans>

Page 18: Spring 3.1

© Zenika 2011 Spring 3.1 18

Environment / ProfileEnvironment / Profile

• Let's reach the clouds!

<bean class="com.zenika.ContactDao"> <constructor-arg ref="dataSource" /></bean>

<beans profile="dev"> <jdbc:embedded-database id="dataSource" type="H2" /></beans>

<beans profile="cloud"> <cloud:data-source id="dataSource" service-name="contactDs"/></beans>

Page 19: Spring 3.1

© Zenika 2011 Spring 3.1 19

Environment / ProfileEnvironment / Profile

• Creating the application context for the test profile

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();ctx.getEnvironment().setActiveProfiles("test");ctx.load("classpath:/application-context.xml");ctx.refresh();

Page 20: Spring 3.1

© Zenika 2011 Spring 3.1 20

Environment / ProfileEnvironment / Profile

• Activating a profile declaratively

-Dspring.profiles.active="prod"

Page 21: Spring 3.1

© Zenika 2011 Spring 3.1 21

Environment / ProfileEnvironment / Profile

• Bootstrapping with the TestContext framework

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:/application-context.xml")@ActiveProfiles("test")public class ProfileTest {

@Autowired private ContactDao contactDao;

@Test public void getContact() throws Exception { ... }

}

Page 22: Spring 3.1

© Zenika 2011 Spring 3.1 22

Environment / ProfileEnvironment / Profile

• Just « prod » profile

<bean class="com.zenika.spring31.ContactDao"> <constructor-arg ref="dataSource" /></bean>

<beans profile="prod"> <jee:jndi-lookup id="ds" jndi-name="java:comp/env/jdbc/ds" /></beans>

Page 23: Spring 3.1

© Zenika 2011 Spring 3.1 23

Environment / ProfileEnvironment / Profile

• Override what you need in the test

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration( loader=AnnotationConfigContextLoader.class)public class SpecialProfileTest {

@Autowired private ContactDao contactDao;

@Test public void getContact() throws Exception { ... }

@Configuration @ImportResource("classpath:/application-context.xml") static class ContextConfiguration { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } }}

Page 24: Spring 3.1

© Zenika 2011 Spring 3.1 24

Java configurationJava configuration

• Nothing equivalent to XML namespaces so far...

@Transactional@Repositorypublic class HibernateContactRepo { ... }

<context:component-scan base-package="com.zenika" />

<tx:annotation-driven />

Page 25: Spring 3.1

© Zenika 2011 Spring 3.1 25

Java configurationJava configuration

• Annotations equivalent to common XML shortcuts

@Transactional@Repositorypublic class HibernateContactRepo { ... }

@Configuration@EnableTransactionManagement@ComponentScan(basePackageClasses=HibernateContactRepo.class)public class ContextConfiguration { ... }

Page 26: Spring 3.1

© Zenika 2011 Spring 3.1 26

Java configurationJava configuration

• Annotations equivalent to common XML shortcuts@Configuration@EnableTransactionManagement@ComponentScan(basePackageClasses=HibernateContactRepo.class)public class ContextConfiguration {

@Bean public SessionFactory sf() throws Exception { return new AnnotationSessionFactoryBuilder() .setDataSource(dataSource()) .setPackagesToScan(Contact.class.getPackage().getName()) .buildSessionFactory(); }

@Bean public PlatformTransactionManager tm() throws Exception { return new HibernateTransactionManager(sf()); }

@Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2).build(); }

}

Page 27: Spring 3.1

© Zenika 2011 Spring 3.1 27

Spring JPASpring JPA

• More support for persistence in Spring JPA

public interface ContactRepository extends JpaRepository<Contact, Long> { }

<jpa:repositories base-package="com.zenika.jpa" />

long initialCount = contactRepo.count();Contact contact = new Contact();contact.setFirstname("Arnaud");contact.setLastname("Cogoluègnes");contactRepo.save(contact);Assert.assertEquals(initialCount+1, contactRepo.count());

Page 28: Spring 3.1

© Zenika 2011 Spring 3.1 28

Spring JPASpring JPA

• Define your own method, following conventions

public interface ContactRepository extends JpaRepository<Contact, Long> {

List<Contact> findByFirstname(String firstname);

}

List<Contact> contacts = contactRepo.findByFirstname("Arnaud");

Page 29: Spring 3.1

© Zenika 2011 Spring 3.1 29

Spring JPASpring JPA

• Define JPQL queries for methods

public interface ContactRepository extends JpaRepository<Contact, Long> {

@Query("from Contact c where lower(c.firstname) = lower(?1)") List<Contact> find(String search);

}

List<Contact> contacts = contactRepo.find("arnaud");

Page 30: Spring 3.1

© Zenika 2011 Spring 3.1 30

Spring JPASpring JPA

• Built-in support for pagination

Pageable request = new PageRequest(1,2,new Sort("lastname")); Page<Contact> page = contactRepo.findAll(request);

List<Contact> contacts = page.getContent();long total = page.getTotalElements();long number = page.getNumberOfElements();

Page 31: Spring 3.1

© Zenika 2011 Spring 3.1 31

Quick note on Spring DataQuick note on Spring Data

• Spring JPA is part of the Spring Data project• Spring Data is an umbrella project• Spring Data provides Spring support for « new » data

access technologies• MongoDB, Neo4j, Riak, Redis, Hadoop

• Support planned for additional NoSQL technologies• HBase, Cassandra, CouchDB

• Don't hesitate to check out Spring Data!• http://www.springsource.org/spring-data

Page 32: Spring 3.1

© Zenika 2011 Spring 3.1 32

Cache support in Spring 3.1Cache support in Spring 3.1

• What about some transparent cache on method calls?

Contact contact = contactRepo.findOne(contact.getId());contact = contactRepo.findOne(contact.getId());

Hibernate: select contact0_.id as id0_0_, ... Hibernate: select contact0_.id as id0_0_, ...

public interface ContactRepository extends JpaRepository<Contact, Long> { Contact findOne(Long id);

}

Page 33: Spring 3.1

© Zenika 2011 Spring 3.1 33

Cache support in Spring 3.1Cache support in Spring 3.1

• Let's combine Spring JPA and Spring 3.1's cache support !• NB: the cache support works on any kinds of beans

public interface ContactRepository extends JpaRepository<Contact, Long> {

@Cacheable("contacts") Contact findOne(Long id);

}

Contact contact = contactRepo.findOne(contact.getId());contact = contactRepo.findOne(contact.getId());

Hibernate: select contact0_.id as id0_0_, ...

Page 34: Spring 3.1

© Zenika 2011 Spring 3.1 34

Cache support in Spring 3.1Cache support in Spring 3.1

• This is how to configure the cache

<cache:annotation-driven />

<bean id="cacheManager" class="o.s.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="o.s.cache.concurrent.ConcurrentMapCache" c:name="contacts" /> </set> </property></bean>

Page 35: Spring 3.1

© Zenika 2011 Spring 3.1 35

Cache support in Spring 3.1Cache support in Spring 3.1

• The cache support is an abstraction• The Spring Framework provides implementations

• SimpleCacheManager• Uses collections of caches• Useful for testing or small, non-distributed environments

• EhCacheCacheManager• Backed up by Ehcache

• The Spring Gemfire project ships with an implementation

Page 36: Spring 3.1

© Zenika 2011 Spring 3.1 36

Cache support in Spring 3.1Cache support in Spring 3.1

• Can use expression for keys

public interface ContactRepository extends JpaRepository<Contact, Long> {

@Cacheable(value="contacts",key="#p0+'.'+#p1") Contact findByLastnameAndFirstname(String lastname, String firstname);

}

Contact contact = contactRepo.findByLastnameAndFirstname( "Cogoluègnes", "Arnaud");contact = contactRepo.findByLastnameAndFirstname( "Cogoluègnes", "Arnaud");

Hibernate: select contact0_.id as id0_, ...

Page 37: Spring 3.1

© Zenika 2011 Spring 3.1 37

Cache support in Spring 3.1Cache support in Spring 3.1

• Method can do some housekeeping with @CacheEvict

@Transactionalpublic interface ContactRepository extends JpaRepository<Contact, Long> {

@Cacheable("contacts") Contact findOne(Long id);

@CacheEvict(value="contacts",key="#p0.id") Contact save(Contact contact);

}

Page 38: Spring 3.1

© Zenika 2011 Spring 3.1 38

Cache support in Spring 3.1Cache support in Spring 3.1

• Spring's cache support can be used • on the data access layer

• replaces 2nd level cache or provides cache for a JDBC-based layer

• at the web tier level• caches business services calls or web services calls

Page 39: Spring 3.1

© Zenika 2011 Spring 3.1 39

Spring MVC enhancementsSpring MVC enhancements

• Easier registration of HttpMessageConverters

• But what is a HttpMessageConverter anyway?

• HttpMessageConverters are used in Spring's REST support• Java object to HTTP response conversion

• From Java to XML, JSON, etc.

• HTTP request to Java object conversion• From XML, JSON to Java

• On the server but on the client side as well...

Page 40: Spring 3.1

© Zenika 2011 Spring 3.1 40

Spring MVC enhancementsSpring MVC enhancements

• Easier registration with a dedicated XML tag• Used to be directly at the HandlerAdapter level

<mvc:annotation-driven> <mvc:message-converters register-defaults="false"> <bean class="com.zenika.web.ContactHttpMessageConverter" /> </mvc:message-converters></mvc:annotation-driven>

Page 41: Spring 3.1

© Zenika 2011 Spring 3.1 41

Spring MVC enhancementsSpring MVC enhancements

• Java-based configuration• Same as <mvc:annotation-driven />

@Configuration@EnableWebMvcpublic class WebConfig extends WebMvcConfigurerAdapter {

@Override public void configureMessageConverters( List<HttpMessageConverter<?>> converters) { converters.add(new ContactHttpMessageConverter()); }

}

Page 42: Spring 3.1

© Zenika 2011 Spring 3.1 42

Spring MVC enhancementsSpring MVC enhancements

• Big refactoring on the way to process annotations

@Controllerpublic class ContactController {

@Autowired private ContactRepository repo;

@RequestMapping(value="/contacts/{id}", method=RequestMethod.GET ) @ResponseBody public Contact get(@PathVariable Long id) { return repo.findOne(id); }

}

Page 43: Spring 3.1

© Zenika 2011 Spring 3.1 43

Spring MVC enhancementsSpring MVC enhancements

• Who used to process annotations like @RequestMapping, @RequestParam, etc?

• Answer: the AnnotationMethodHandlerAdapter.• Processing was hard-coded in the class• Spring 3.1 introduced the HandlerMethod abstraction

• RequestMappingHandlerMapping• RequestMappingHandlerAdapter

Page 44: Spring 3.1

© Zenika 2011 Spring 3.1 44

Spring MVC enhancementsSpring MVC enhancements

• Consequences of the HandlerMethod abstraction• Backward compatible (@RequestMapping, @RequestParam

& co).• More fine-grained control over controller method execution• Possible interception around the invocation of the controller• Pluggable mechanism on method argument

• You can create your own @RequestParam-like annotations!• Check the HandlerMethodArgumentResolver and HandlerMethodReturnValueHandler interfaces

Page 45: Spring 3.1

© Zenika 2011 Spring 3.1 45

Support for Servlet 3.0Support for Servlet 3.0

• Servlet 3.0 allows for programmatic registration• ServletContext.addServlet(String, Servlet)• ServletContext.addFilter(String, Filter)

• Hook for frameworks• ServletContainerInitializer• Implementations listed in META-INF/services

• In Spring: SpringServletContainerInitializer

Page 46: Spring 3.1

© Zenika 2011 Spring 3.1 46

Support for Servlet 3.0Support for Servlet 3.0

• SpringServletContainerInitializer triggers WebApplicationInitializers

• WebApplicationInitializer• The API to use• Detected and called by Spring (through the web container)• Used for initialization

• Registering a DispatcherServlet• Bootstrapping the Spring ApplicationContext

Page 47: Spring 3.1

© Zenika 2011 Spring 3.1 47

Support for Servlet 3.0Support for Servlet 3.0

• No need of web.xml anymorepublic class ZenContactInitializer implements WebApplicationInitializer {

@Override public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(WebConfig.class); sc.addListener(new ContextLoaderListener(rootContext));

AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); dispatcherContext.register(DispatcherConfig.class);

ServletRegistration.Dynamic dispatcher = sc.addServlet( "dispatcher", new DispatcherServlet(dispatcherContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/main"); }}

Page 48: Spring 3.1

© Zenika 2011 Spring 3.1 48

ResourcesResources

• Summary• http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/

• http://blog.springsource.com/2011/06/09/spring-framework-3-1-m2-released/

• Environment• http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/

• http://blog.springsource.com/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/

• http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/

• Cache abstraction• http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/

• Spring JPA• http://blog.springsource.com/2011/02/10/getting-started-with-spring-data-jpa/

• http://blog.springsource.com/2011/07/27/fine-tuning-spring-data-repositories/

• Spring MVC• http://blog.springsource.com/2011/02/21/spring-3-1-m1-mvc-namespace-

enhancements-and-configuration/

• http://blog.springsource.com/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2/

Page 49: Spring 3.1

© Zenika 2011 Spring 3.1 49

Questions ?