Spring 3.1 M2: Configuration Enhancements |
|

As Juergen mentioned in his post yesterday, and as I've mentioned in my previous posts on 3.1 M1, one of the major themes of Spring 3.1 is completing our vision for code-based configuration in Spring. We think a modern enterprise Java application should have a choice between Java and XML as first class options for its configuration. In this post we'll see how Spring 3.1 M2 helps make this a reality.
Note that although Java-based configuration has been available since Spring 3.0, with this release it is now on par with many more of the XML-based features that have been developed over the years. We think the result is very appealing, and in some cases even offering clear advantages over XML-based configuration. In short: if you didn't consider it in 3.0 you really should look at it closely this time around.
Code equivalents for Spring's XML namespaces
If you've been watching things closely, you'll recall that we introduced the idea of FeatureSpecification classes and @Feature methods in 3.1 M1. As it turns out, we've decided to replace this with a different mechanism in 3.1 M2. Why? Because although FeatureSpecification classes provided a convenient mechanism for configuring features of the Spring container like annotation-driven transaction management and component-scanning, that convenience came with two downsides: lack of extensibility, and lack of implementation transparency. The more we thought about it, the more we realized we could do even better. While FeatureSpecification classes mirrored the XML namespaces closely through fluent APIs, the new solution takes a different shape – one specifically designed to take advantage of Java on its own terms.
For short, we call the new mechanism "@Enable" annotations. These annotations are applied at the type level on @Configuration classes. Let's take @EnableTransactionManagement for an example. Most users will be familiar with the following Spring XML snippet:
<beans> <tx:annotation-driven/> </beans>
This of course enables Spring's support for transaction management using the @Transactional annotation. Now let's see the equivalent configuration in code:
@Configuration
@EnableTransactionManagement
public class AppConfig {
// ...
}
Pretty simple, huh? Of course there's much more to say, and I would encourage everyone to take a look at the Javadoc for the @Enable annotations we've delivered in this release. You'll find they contain plenty of context, examples and references to important related types. It should be everything you need to get started. Of course, we'll also be updating the reference documentation prior to 3.1 GA, but we skipped this for M2 simply because the Javadoc has seen a lot of love.
Take a look as well at the Javadoc for @Configuration, which has been revised considerably in M2 to show off the major integrations with other annotations and mechanisms like the new Environment abstraction.
Regarding the @EnableWebMvc annotation, this is one great example where Java-based configuration proves to have real benefits over the XML namespace alternative. Rossen will be posting on this topic in detail later in this series, so stay tuned for that.
Hibernate SessionFactory builder APIs
Spring's support for Hibernate has always been one of the more popular features of the framework, and it's always been configured via XML. In M2 we've introduced the SessionFactoryBuilder and AnnotationSessionFactoryBuilder APIs which make code-based configuration of the Hibernate SessionFactory a snap. Check it out:
@Configuration
public class DataConfig {
@Bean
public SessionFactory sessionFactory() {
return new AnnotationSessionFactoryBuilder()
.setDataSource(dataSource())
.setPackagesToScan("com.myco")
.buildSessionFactory();
}
}
See the Javadoc for more examples and specific details:
XML-free JPA configuration
Spring users working with JPA will be familiar with our LocalContainerEntityManagerFactoryBean. We've added a 'packagesToScan' property that allows you to drop persistence.xml altogether! This is, by the way, very similar to the property of the same name on Spring's Hibernate AnnotationSessionFactoryBean. Here's an example:
@Configuration
public class DataConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf =
new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource())
emf.setPackagesToScan("com.myco")
return emf;
}
}
Leaving web.xml behind
Servlet 3.0 introduces some very interesting new facilities for code-based configuration of the servlet container. Essentially, the ServletContext API has been enhanced to allow users to register servlets, filters and listeners in a class-based or instance-based fashion. Take a look:
This means that it's now possible to register servlet-oriented components like Spring's DispatcherServlet and ContextLoaderListener programmatically, instead of declaratively via web.xml.
All that's missing is a bootstrap mechanism — a place to perform these registrations at a well-defined point in the servlet container lifecycle. Fortunately, Servlet 3.0 addresses this as well, with ServletContainerInitializer.
ServletContainerInitializer is a low-level SPI primarily targeted for use by frameworks like Spring. I'll leave the details to the Javadoc (links below), but in short, Spring 3.1 M2 now provides a very convenient WebApplicationInitializer interface that works in concert with the ServletContainerInitializer SPI to allow you to bootstrap the servlet container programmatically. Here's a quick example:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext()
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
As you can see, DispatcherServlet now sports a constructor that accepts a WebApplicationContext. Here's the Javadoc:
And while we used an XmlWebApplicationContext above, you can of course opt for AnnotationConfigWebApplicationContext instead and bootstrap completely via @Configuration classes.
When the spring-web module JAR is present on your classpath, your WebApplicationInitializer implementation(s) are detected and processed automatically by Spring in conjunction with the ServletContainerInitializer mechanism. This means you can package them exactly as you see fit in your application (goodbye, WEB-INF!) We've tested all of this successfully on Glassfish 3.1 and Tomcat 7.0.15, so now is a great time to get your feet wet with both Spring 3.1 and Servlet 3.0.
For complete usage instructions, take a look at the Javadoc for WebApplicationInitializer itself:
And for a complete (and concise) example of migrating from web.xml WebApplicationInitializer, check out this commit from the 'servlet3' branch of Spring's Greenhouse reference application:
- Greenhouse
web.xml -> WebApplicationInitializer
Improved support for externalized values
M1 introduced the Environment abstraction and a unified PropertySource API. In M2, our goal is to make these components as easy to configure and use as possible. The new @PropertySource annotation allows you to contribute property sources to the environment from within your @Configuration classes:
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
This is a different approach from the traditional PropertyPlaceholderConfigurer (<context:property-placeholder>) approach. Here, we're contributing a property source to the environment, injecting the environment into our @Configuration class, and then looking up the properties needed using the environment's #getProperty family of methods. Check out the Javadoc for @PropertySource and Environment for full details.
- @PropertySource
- Environment
- PropertyResolver (superinterface for Environment)
Summary
As you can see, we really do have a major theme going on here. From Java-based alternatives to Spring's XML namespaces and FactoryBeans to eliminating even non-Spring XML like web.xml and persistence.xml, we can now proudly say that Spring's code-based configuration is first-class throughout the framework. The only thing remaining is your feedback!
As Juergen mentioned, now is the time to try out 3.1 if you haven't already started. We're moving into the release candidate phase now, which is the perfect time to make improvements based on your real-world usage. Please let us know how it goes!
Oh, and one more thing… If you haven't already noticed, Spring is now on Twitter! Follow @springframework to stay up to date with releases and for insights into Spring from the framework itself. Hope to see you there and thanks for reading!
Similar Posts
- Migrating to Spring 3.1 and Hibernate 4.1
- Spring Framework 3.1 goes GA
- Spring Framework 3.1 RC1 released
- Spring 3.1 M1: Unified Property Management
- Spring Framework 3.1 M2 released





Javier says:
Added on June 10th, 2011 at 9:01 amI'm really excited with this new version and it's features.
The development process of my company is going to speed up a lot with all of this.
However, two issues come to my mind inmediatly:
- In which version of IBM WebSphere could be deployed this programming model? WAS is the app server chosen by my company and sadly WAS 6.1 is the current version that we're using.
- How long will it take to the rest of the Spring modules (Security, Roo and so on) to being adapted to this new release?
In any case, good job and thanks for the effort.
Jon Bristow says:
Added on June 10th, 2011 at 1:14 pmI want to use Java Configuration in my existing setup, but Spring IDE doesn't seem to know how to parse configuration beans properly. I had to switch back to XML configuration because I couldn't take all the erroneous warnings!
Marcel Overdijk says:
Added on June 10th, 2011 at 1:24 pmHow would one migrate
to the @PropertySource annotation?
I tried @PropertySource({"classpath:/META-INF/config.properties", "classpath:/META-INF/config-${com.google.appengine.runtime.environment}.properties"})
but this doesn't work. FileNotFoundException for /META-INF/config-${com.google.appengine.runtime.environment}.properties
{com.google.appengine.runtime.environment} is a System Property. It works with the XML property placeolder. S
Marcel Overdijk says:
Added on June 10th, 2011 at 2:31 pmI just see my previous post didn't worked (xml was removed).
I created this forum topic on the Spring forum: http://forum.springsource.org/showthread.php?110538-Spring-3.1.0.M2-PropertySource-flexibility&p=366504#post366504
Juergen Hoeller (blog author) says:
Added on June 10th, 2011 at 2:34 pmJavier, we do actually support WebSphere 6.1 still – and will keep up that support level for the entire Spring Framework 3.x branch. Our basic requirements are just Java SE 5 and Servlet 2.4 .
You can deploy almost all of this model on WebSphere 6.1. Just Servlet 3.0 won't be available (that would require WebSphere 8), so you'll have to stick with web.xml for the time being – a minor limitation only.
Juergen
Joris Kuipers (blog author) says:
Added on June 10th, 2011 at 5:15 pmGreat work guys! Any hint on where Tomcat 7.0.15 can be downloaded for those who want to try out the new Servlet 3.0 features? http://tomcat.apache.org/download-70.cgi only has 7.0.14 at the moment, which I think has a bug that prevents these features from working properly.
Donny says:
Added on June 10th, 2011 at 6:01 pmDoes packagesToScan support finding and scanning the ORM.xml (or mapping files) in the package. This will make easier to write the JPA queries
Javier says:
Added on June 11th, 2011 at 3:59 amThanks for the information, Juergen.
Harald Wellmann says:
Added on June 12th, 2011 at 10:25 amCool, I'm looking forward to get rid of XML configuration completely! But what about the jee: namespace? Is there also an @EnableJavaEE annotation?
Chris Beams (blog author) says:
Added on June 12th, 2011 at 11:38 pm@Joris – grab 7.0.15 here: http://people.apache.org/~markt/dev/tomcat-7/v7.0.15/
Chris Beams (blog author) says:
Added on June 12th, 2011 at 11:39 pm@Donny – thanks for submitting https://jira.springsource.org/browse/SPR-8440. We'll check it out.
Chris Beams (blog author) says:
Added on June 12th, 2011 at 11:45 pm@Marcel – as commented at https://jira.springsource.org/browse/SPR-8442:
@PropertySource resource locations now support resolution of ${…} placeholders.
See updated Javadoc at https://build.springsource.org/browse/SPR-TRUNKQUICK-JOB1-3772/artifact/javadoc-api/org/springframework/context/annotation/PropertySource.html
Chris Beams (blog author) says:
Added on June 12th, 2011 at 11:57 pm@Harald – There will probably not be a dedicated equivalent for the jee: namespace. A JNDI lookup, for example, can be done programmatically without downsides within a @Bean method. You can do this with the native InitialContext API, or with Spring's JndiTemplate, if you choose.
Chris Beams (blog author) says:
Added on June 12th, 2011 at 11:58 pm@Jon – regarding spurious warnings in STS when using @Configuration classes, please feel free to create an issue at https://issuetracker.springsource.com/browse/STS.
Tobias says:
Added on June 20th, 2011 at 1:51 amI really like the @PropertySource annotation. It would be even more convenient if you don't have to inject the environment but could use @Value for getting the properties from the environment. Is that possible? Or planned?
Chris Beams (blog author) says:
Added on June 20th, 2011 at 2:14 am@Tobias,
Either approach will work. See the "Working with externalized values" section of the Javadoc for @Configuration:
http://static.springsource.org/spring/docs/3.1.0.M2/javadoc-api/org/springframework/context/annotation/Configuration.html
However, you may find that using context:property-placeholder and @Value is more cumbersome than necessary. When working directly against an injected Environment, there's no need to register the property-placeholder at all. And it tends to be the case that if you need one @Value injected, you need many (think about standard JDBC datasource properties, for example. Why not simply inject the Environment once and then perform lookups against it? Should be more concise and clear in the end. However, the choice is yours!
Paul Middelkoop says:
Added on June 22nd, 2011 at 4:35 amIs it possible to set the JPA 2 specific SharedCacheMode using the XML-free JPA configuration?
Juergen Hoeller (blog author) says:
Added on June 22nd, 2011 at 12:15 pmYes, you can set the "javax.persistence.sharedCache.mode" property on LocalContainerEntityManagerFactoryBean (through its "jpaProperties"/"jpaPropertyMap").
Juergen
Gabuzo says:
Added on June 23rd, 2011 at 10:21 am@Chris Beams,
I do agree that setting a property-placeholder is cumbersome and overkill. Performing getProperty on the environment is OK but I guess being able to inject the properties directly through the @Values (or another) annotation will be even better.
Tobias says:
Added on June 23rd, 2011 at 11:34 am@Chris and Gabuzo
That was my question: using @PropertySource and @Value without having to register a PropertySourcesPlaceholderConfigurer would be more convenient than injecting the environment and calling getProperty on it.
Using @PropertySource could maybe register a PropertySourcesPlaceholderConfigurer automatically.
Chris Beams (blog author) says:
Added on June 24th, 2011 at 11:09 pm@Tobias, @Gabuzo,
Just a point of clarification on the comments above. Are you referring to using @Value in @Configuration classes or within individual @Component classes?
In the case of @Configuration, I'd like to hear more why you find @Value injection to be better. In practice, we've found that this usually results in more verbosity, assuming that each @Value is individually injected into a field, and those fields then being referenced from within one or more @Bean methods. By contrast, @Inject'ing the Environment requires only one field, and then the #getProperty lookups are quite flexible and natural from that point forward.
Please fill me in on why you would continue to prefer @Value injection into @Configuration classes, if that's actually the case.
As for @Component classes, @Value injection is a good measure more appropriate there. Very often a @Component may need only one or two @Values injected, and the user may not want to depend so directly on a Spring interface like Environment in that context.
Regarding automatic registration of a PropertySourcesPlaceholderConfigurer when using @PropertySource, I'm not sure this is the best approach given that it's not always what's desired, e.g. when going the Environment injection route. It's certainly easy enough to simply declare a @Bean method that returns a PSPC, and we could consider adding an @Enable annotation that does the same. Feel free to add an issue to this effect in JIRA if you like.
Tobias says:
Added on June 26th, 2011 at 6:21 am@Chris
I was talking about @Configuration classes, but I got your point. The more I think about it, the more I like your approach. It's even a little less annotation magic.
And about an enable annotation for the propertyplaceholder: don't think that's necessary, because it's just a three liner @Bean method it would be replacing. On the other hand that's what the propertyplaceholder tag does: replacing three lines with one.
Matt says:
Added on June 27th, 2011 at 4:55 pmHey guys -
These are some of the enhancements I'm most looking forward to with Spring 3.1. I've been using 3.1M2 to try to get the persistence.xml-less JPA instantiation running (using OpenJPA 2.1). Do you all know of an example yet with an XML Spring config that wires all the magic together correctly? I'm getting complaints about not having a persistence unit specified (which normally is in the persistence.xml file) and I'm not quite sure where or how to declare it.
Thanks again,
Matt
Matt says:
Added on June 27th, 2011 at 5:17 pmAnd once you post something, you're sure to find the answer:
HHD says:
Added on June 28th, 2011 at 4:46 pmI am looking for a good example of getting Servlet 3.0 (sans web.xml), Spring 3.1 and Spring Security to all work together well. Old school is easy, but this isn't.
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext
= new AnnotationConfigWebApplicationContext();
applicationContext.scan("com.companyx.projectx");
applicationContext.refresh();
servletContext.addListener(new ContextLoaderListener(applicationContext));
DelegatingFilterProxy delegatingFilterProxy
= new DelegatingFilterProxy("springSecurityFilterChain", applicationContext);
servletContext.addFilter("???", delegatingFilterProxy);
Any help or direction to a helpful post would be very much appreciated. Thanks!
Chris Beams (blog author) says:
Added on June 29th, 2011 at 12:04 am@Tobias: Great, thanks for the follow-up.
@Matt: Glad to hear you got what you need. Your link didn't come through. For posterity's sake, what was the example that ended up helping you?
@HHD: In your example above, the "???" argument to #addFilter should simply be "springSecurityFilterChain". This is the equivalent of the filter-name element from web.xml. Does that get get you what you need?
Also, if you don't actually need to #refresh() the context, it's better to let the ContextLoaderListener do this work for you. Both approaches are supported, but in your case, you can simply remove the call altogether.
HHD says:
Added on June 30th, 2011 at 11:41 am@Chris Thanks. That did help. It all ended up, be it right or wrong, like this:
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext
= new AnnotationConfigWebApplicationContext();
applicationContext.scan("com.projectx");
servletContext.addListener(new ContextLoaderListener(applicationContext));
DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy("springSecurityFilterChain", applicationContext);
FilterRegistration fr = servletContext.addFilter("springSecurityFilterChain", delegatingFilterProxy);
fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), true, "/**");
ServletRegistration.Dynamic dispatcherServlet
= servletContext.addServlet("dispatcherServlet", new DispatcherServlet(applicationContext));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/app/*");
}
That at least registers the security filter programmatically, judging from the logs at startup. However, for
some reason … and it was working fine when using the web.xml approach versus with WebAppInitializer (which
implements WebApplicationInitializer) … it is not seeing my UserDetailsServiceImpl and thus never seems to
succeed. Is that a known issue, happening only when using the programmatic approach to bootstrapping?
Oh well. Pilot error? Often, yes. This time – I don't think so!
I also hate having this: dispatcherServlet.addMapping("/app/*");
I really don't like having to have "app" in there, but it doesn't seem to work any other way. http://localhost:8080/projectx/index -vs- http://localhost:8080/projectx/app/index
Thanks for all.
–
Henry Dall
Chris Beams (blog author) says:
Added on June 30th, 2011 at 12:19 pm@Henry,
A couple things jump out, though they may not be the solution to your problem. First, it's probably not a good idea to try supplying the same applicationContext instance to both the ContextLoaderListener and the DispatcherServlet. These are really designed to be separate context instances that are then linked together by the dispatcher servlet in a hierarchical fashion. Consider using the no-arg constructor for DispatcherServlet or creating a distinct child context.
Second, there shouldn't be any problem mapping "/*" instead of "/app/*", so long as you're on Tomcat 7.0.15 . What is your target platform here?
Finally, this is probably isn't the best venue to continue such a detailed discussion. Consider submitting a pull request against the spring-framework-issues project (see the README at http://bit.ly/jTHHZ6), and we can look into this further via working code. Thanks!
Dave Fogel says:
Added on July 12th, 2011 at 8:36 amWe currently use Spring 3 with Spring DM in an OSGi environment, and we do most of our configuration using @Configuration config classes. We'd like to use this java-config style for everything, but so far we haven't been able to figure out how to avoid having an XML file to declare osgi:reference and osgi:service beans.
Is there anything in the new release that would enable us to declare our OSGi services and service references in our @Configuration code instead?
Marcel Overdijk says:
Added on July 28th, 2011 at 4:54 pmHi Chris,
What would be the best way to configer StringTrimmerEditor globally using Spring 3.1 with Java Config?
ake says:
Added on September 1st, 2011 at 6:37 amRalph says:
Added on October 26th, 2011 at 6:16 amA little late but I just figured out that it's possible to use @Value togehter with @PropertySource. Here an example
@Value("#{environment.driverClassName}")
private String driverClassName;
Kevin says:
Added on October 27th, 2011 at 6:44 amExcellent presentation at SpringOne yesterday on the new configuration. Your willingness to descend the discussion below the API that developers are accustomed to working with was very appreciated. It was insightful to hear why the Spring development team made certain decisions and gave me a better understanding of the framework. Content was extremely clear and focused, great job! Looking forward to the final release of 3.1 and your Getting Involved Session today.
Chris Beams (blog author) says:
Added on October 31st, 2011 at 12:12 pmThanks, @Kevin!
psilos says:
Added on November 16th, 2011 at 6:57 amI was trying to use AnnotationSessionFactoryBuilder with the latest spring 3.1.RC1 but couldn't find it anymore.
Are these Builders deprecated now? What could be the best alternative of a Hibernate Session Factory with @Configuration classes?
Thanks!
Chris Beams (blog author) says:
Added on November 16th, 2011 at 12:47 pm@psilos,
Indeed, we backed these out in RC1. This commit explains why, and makes note of the "LocalSessionFactoryBuilder" replacement in the orm.hibernate4 package.
https://github.com/cbeams/spring-framework/commit/011e123e3fbc0a42600f60dec01f9d2ba02478ae
Joe Gaber says:
Added on December 15th, 2011 at 12:23 amChris,
The link above gets a 404. There seems to be a number of spring classes that are in the Greenhouse sample project that are no longer available in 3.1.0.RELEASE. Examples:
org.springframework.jdbc.versioned.DatabaseChangeSet; org.springframework.jdbc.versioned.SqlDatabaseChange org.springframework.social.facebook.web.FacebookHandlerMethodArgumentResolver org.springframework.social.mobile.device.DeviceHandlerMethodArgumentResolver;
Is there a place that has a map or explanation of where they went to or what replaced them?
Thx
CsCsaba says:
Added on December 20th, 2011 at 10:52 amHello,
Ok, I see that how can we configure jpa and hibernate without xml.
But in case of jpa config where will the hibernate come into the picture ?
As I know, we cant use jpa without Hibernate so where is connection between them ?
Thanks in advance.
CsCsaba
Paul Middelkoop says:
Added on December 20th, 2011 at 10:58 amHi CsCsaba.
The connection is made by setting the persistence provider to Hibernate on the LocalContainerEntityManagerFactoryBean. Like this:
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setPersistenceProvider(new HibernatePersistence());
Regards,
Paul
CsCsaba says:
Added on December 20th, 2011 at 8:52 pmThanks Paul!
Gareth Hughes says:
Added on February 28th, 2012 at 2:58 amIf you want to put this together with Java configuration files -
Read the javadocs for @Configuration
In a nutshell you would put the following inside a spring config file :
@Autowired Environment env;
(note that the Javadoc says you can use @Inject but that's not working)
then you can
@Bean
public Foo getMyFoo(){
String user = env.getProperty("USER_NAME");
return new Foo(user);
}
mark says:
Added on October 24th, 2012 at 5:13 pmHey!
How about editing the blog posts (near the top) to indicate that these ideas are deprecated?!
Chris Beams (blog author) says:
Added on October 25th, 2012 at 1:57 am@mark, to which "deprecated ideas" are you referring? The content of this blog post is still accurate unless I've overlooked something. In any case, your comment reminded me that I should add such a note to the earlier 3.1 M1 blog post which announced
FeatureSpecificationsupport – a concept that was indeed replaced with@Enableannotations. I've added an update to the beginning of that article, but am still unsure what you're referring to in this one. Thanks.Mark says:
Added on October 25th, 2012 at 7:37 amChris….Oops, I was reading both articles and posted my earlier comment on the wrong one. I meant to post the "deprecated" comment on the earlier 3.1 M1 blog post. Thanks for the quick response
Diego says:
Added on December 19th, 2012 at 6:39 amChris,
Is there an alternative to write the datasource programmatically?
Ex:
Diego says:
Added on December 19th, 2012 at 6:39 amChris,
Is there an alternative to write the datasource programmatically?
Ex:
Diego says:
Added on December 19th, 2012 at 6:40 amThe code didn't went on the comment
jee:jndi-lookup id="dataSource" jndi-name="java:/couponpublisher-ds"