More on Java Configuration
As most of you already know by now, Spring is not just about XML as lately, a number of 'official' extensions to the core offer alternatives way for configuring the container.
Spring Java Configuration 1.0 M2 was among the products released around JavaOne and, while still marked as a milestone, had an important number of updates and bugfixes:
In fact, most of the work done for 1.0 M2 was incorporating the feedback received to the initial announcement; thanks a lot to everybody involved!
In this entry, I'd like to give some examples of Java Configuration, as a true IoC annotation-based configuration.
Let's start off with Mark's example, used in his entry on Spring 2.1 annotation-driven dependency injection.
To recap, below is a diagram of the interfaces and classes used by Mark:

The wiring is done through @Autowired while some methods are marked as being part of the lifecycle, through @PostConstruct and @PreDestroy.
Translating the annotation-driven configuration to Java Configuration is pretty straight forward:
public abstract class JavaCfg {
@Bean (destroyMethodName = "tearDownDatabase")
public JdbcMessageRepository messageRepo() {
JdbcMessageRepository repo = new JdbcMessageRepository();
repo.createTemplate(dataSource());
// call custom init method
repo.setUpDatabase();
return repo;
}
@Bean
public GreetingService greetService() {
GreetingServiceImpl impl = new GreetingServiceImpl();
impl.setMessageRepository(messageRepo());
return impl;
}
@ExternalBean
public abstract DataSource dataSource();
}
First, the configuration is created using a Java class marked with @Configuration. In it, 2 beans are being declared and an external one referenced.
The first bean declared is messageRepo (same as the method name) which defines also a destruction method. Notice that the custom init method is invoked through the code and thus doesn't need any annotation or declaration. You can still use Spring InitializingBean interface or the @Bean initMethodName parameter though I would recommend against that. The code above is much clearer and concise not to mention that you can pass in arguments, something unavailable when using declarative init methods.
The second bean defined is greetService which uses messageRepo as a dependency. This is where the Java Configuration magic occurs since each time greetService will be created, the Spring container will supply the bean instance behind messageRepo. That is, if messageRepo is a singleton, the same instance will be returned each time. However, if a different scope is specified, then, when a new instance has to be created, your code will be invoked. Rod already explained this so please refer to his blog entry for more information.
One addition to 1.0 M2 is the @ExternalBean annotation which references beans declared outside the current configuration while still relying on Java strong-typeness and thus, your IDE validation. @ExternalBean overrides at runtime the method it is declared on with a getBean() lookup, like this:
return (DataSource) context.getBean("dataSource");
}
Of course, one can do the same thing manually especially when using ConfigurationSupport class but @ExternalBean makes things a lot more easier. Note that in the initial example I have used an abstract method to emphasize externalization, however any type of non-final method can be used:
public DataSource dataSource() {
throw new UnsupportedOperationException("this line will NEVER execute since the method will be overridden");
}
Now that the configuration has been created, declare it as a normal bean along with the JavaConfiguration post processor:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="config" class="blog.javaconfig.JavaCfg" />
<bean id="processor"
class="org.springframework.config.java.process.ConfigurationPostProcessor" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>
and you are ready to go (if you are running Mark's test, make sure to use the Java Configuration xml file).
Since a picture is worth a thousands words, see below the same setup through SpringIDE:

I've used the latest SpringIDE snapshot which offers visualization, navigation and also validation for Java Configuration annotations (for example the plugin checks that destroyMethodName points to a proper method on the bean creation method return type).
Hide and seek
Java Configuration supports most of the XML declaration features, that is you can specify scopes, autowire strategies, lazyness, depends-on as well as custom metadata at bean level (through @Bean) and as defaults (through @Configuration). In 1.0 M2 you even get the @ScopedProxy annotation, a direct replacement for <aop:scoped-proxy/>.
However, one new feature that Java Configuration offers over the traditional XML container is "bean visibility" - the ability to define beans which cannot be used outside their configuration. Again, let's look at some code:
public class VisibilityConfiguration {
@Bean(scope = DefaultScopes.PROTOTYPE)
public Object publicBean() {
List list = new ArrayList();
list.add(hiddenBean());
list.add(secretBean());
System.out.println("creating public bean");
return list;
}
@Bean(scope = DefaultScopes.SINGLETON)
protected Object hiddenBean() {
System.out.println("creating hidden bean");
return new String("hidden bean");
}
@Bean(scope = DefaultScopes.PROTOTYPE)
private Object secretBean() {
List list = new ArrayList();
// hidden beans can access beans defined in the 'owning' context
list.add(hiddenBean());
System.out.println("creating secret bean");
return list;
}
}
Java Configuration will use the method visibility to determine if a certain bean is public (that is if it can be used outside its declaring configuration) or private (non-public). Thus any @Bean annotated method, which is non-public, will create a hidden bean. This allows you to provide bean definition encapsulation, forbidding access whether accidental or not.
It is very important to note that hidden beans are not transformed into nested beans - they are fully featured, top-level beans: they have their own lifecycle and support custom scopes as opposed to inner beans which depend on the parent bean.
To prove this, I've marked the hiddenBean as singleton and secretBean as prototype.
Let's test the behavior with the following test:
private ConfigurableApplicationContext context;
@Override
protected void setUp() throws Exception {
context = new AnnotationApplicationContext("**/VisibilityConfiguration.class");
}
@Override
protected void tearDown() throws Exception {
context.close();
}
public void testApplicationContext() {
assertNotNull(context);
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
// I don't belive you container! I know you are hidding something
context.getBean("hiddenBean");
}
}
The test should print:
creating hidden bean
creating secret bean
creating public bean
creating secret bean
creating public bean
after which should fail with something like:
…
The first line in the console shows that secretBean and hiddenBean are not defined in the context that we hold. However, the following lines, show that the hidden bean is created once (since it is a singleton) while secretBean twice, for each publicBean, as it is a prototype.
So where are the hidden beans then? Inside a child container.
The parent container (context in our case) is completely unaware of it and thus, of any beans declared inside it. Nevertheless, beans declared inside the child context can access any beans declared inside the parent but not vice-versa. Public beans (such as publicBean) on the other hand, are 'pushed' by Java Configuration inside the parent container, but since they are declared in the same configuration as the hidden bean, they can reference the 'secret' beans during instantiation.
Look Ma', no XML!
For those who want to ditch XML completely, Spring Java Configuration offers the AnnotationApplicationContext which uses classes rather then XML files, as you could see from the test case above. While my example works,it is not ideal since, without any caching, the application context will be created and destroyed for each test.
An alternative is to reuse the existing AbstractDependencyInjectionSpringContextTests and override the context creation appropriately:
@Override
protected ConfigurableApplicationContext createApplicationContext(String[] locations) {
GenericApplicationContext context = new GenericApplicationContext();
customizeBeanFactory(context.getDefaultListableBeanFactory());
// use Java Configuration annotation-based bean definition reader
new ConfigurationClassScanningBeanDefinitionReader(context).loadBeanDefinitions(locations);
context.refresh();
return context;
}
@Override
protected String[] getConfigLocations() {
return new String[] { "**/*.class" };
}
public void testAppCtx() {
assertNotNull(applicationContext);
}
}
(this can be further simplified through SPR-3550).
Which approach is better?
Some of you might wonder what is the best annotation configuration approach: annotation-driver injection or Java Configuration? My answer is: "it depends".
Java Configuration stays true to the IoC principle as the configuration resides outside your code, which means you have true POJOs (i.e. no configuration annotations inside your code).
The annotation-driven injection presented previously on this blog, allows objects to be a little more aware of their configuration. They can ask for dependencies, for autowiring and can even specify their scope. The injection still occurs (that is the objects are still managed by the container), but some parts of your configuration are now contained by your objects.
With JavaConfig you can configure your objects without any restrictions as you are using pure Java. You can use any number of arguments, of any type and can call any number of methods. Since it is Java, your configuration is refactoring friendly and you can benefit from your IDE auto-completion. This is extremely flexible and powerful!
On the other hand, with annotation-driven injection, you have fine-grained (class, method and even field-level) control over your objects as well as a lot more contextual information.
Consider the @Autowire method:
public void createTemplate(DataSource dataSource) {
this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
Spring uses the annotation not just to determine the method on which the autowiring will occur, but also the required type(s). Moreover, multi-arg methods can be used, a feature not supported by 'traditional' autowiring which uses the JavaBeans convention and thus, setters.
At the end of the day, both approaches serve one purpose: to configure the Spring container. You can use one of them, or both along with some XML and properties on top if you'd like. In fact, the Java Configuration distribution, replaces the 'traditional' XML configuration for Petclinic with an XML, annotations and Groovy based configuration. Considering this blog entry, it won't be long until JRuby will be included.
The bottom line is that you have the choice to pick whatever fits your development style better.
P.S. If you are interested in this topic, you might want to attend the following SpringOne session for an in-depth discussion ![]()
Cheers,
Costin

Magnus Heino says:
Added on June 5th, 2007 at 2:45 amWhat about AOP, @Aspect, @Transactional etc?
Costin Leau (blog author) says:
Added on June 5th, 2007 at 2:59 am[quote comment="25793"]What about AOP, @Aspect, @Transactional etc?[/quote]
What about them? These annotations are handled by the AOP infrastructure, which is orthogonal to Java Configuration which provides configuration and injection.
Magnus Heino says:
Added on June 5th, 2007 at 4:13 amOk.
https://svn.sourceforge.net/svnroot/springframework/repos/ please?
Costin Leau (blog author) says:
Added on June 5th, 2007 at 4:35 amHmm…for some reason the maven artifacts haven't been published yet (which is strange). I'll let you know ASAP, once they are up.
Costin Leau (blog author) says:
Added on June 5th, 2007 at 7:28 amMagnus, you can find the maven artifacts at: https://svn.sourceforge.net/svnroot/springframework/repos/repo-snapshots/org/springframework/spring-javaconfig/
Magnus Heino says:
Added on June 5th, 2007 at 8:31 amThanks!
pom seems to need some tweaking?
All (?) other poms get aopalliance from aopalliance/aopalliance, not org.aopalliance/aopalliance. I get a duplicate now and have to exclude it.
All aspectj-dependencies are scoped as test, but I get class not found on
org/aspectj/lang/reflect/AjTypeSystem
Costin Leau (blog author) says:
Added on June 5th, 2007 at 9:17 amPlease raise an issue on Spring JavaConfig and assign it to Ben Hale - the maven guy.
Thanks!
Taras Tielkes says:
Added on June 5th, 2007 at 2:51 pmI've already raised one last week: http://opensource.atlassian.com/projects/spring/browse/SJC-18
Magnus Heino says:
Added on June 7th, 2007 at 3:37 amWhat about properties?
Can I do myBean.setUrl("${jdbc.url}"); and have that resolved by a PropertyPlaceholderConfigurer later on? Is there a best practice for this?
Today I have 8 spring-xml config files. If I want to javaconfig-ify this app, how would I do it? One java-file with everything, 8 java-files with @ExternalBean duplicated for all beans referenced in between files, or is it possible to create static methods that are @Bean annotated?
Costin Leau (blog author) says:
Added on June 7th, 2007 at 4:01 amPropertyPlaceholderConfigurer is a BeanFactoryPostProcessor which works on bean definitions - it won't work with Java Configuration since you are configuring directly the bean instance w/o an intermediate form.
For now, as in my SpringIDE snapshot, I would recommend using an XML definition for your datasource. There isn't any value, IMO, for supporting PropertyPlaceholder inside Java since you don't have any validations - you just pass in a String which is better of externalized.
Of course, suggestions are welcomed.
As for your configuration files, identify why you have the division between them and based on, decide whether you want one or more configuration classes. You can define a base class with @ExternalBean to simplify things or you could use ConfigurationSupport along with a base getBean() method which you can reuse:
public DataSource dataSource() {
return (DataSource) getBean("dataSource");
}
@Bean
public Object someBean() {
MyBean bean = new MyBean();
bean.setDataSource(dataSource());
….
return bean;
}
}
Costin Leau (blog author) says:
Added on June 25th, 2007 at 4:56 amMagnus, I've spoked with Ben Hale at SpringOne about the maven release and SJC and we decided to address this issue properly in the next release. Right now, there is code that could use classpath detection to determine if, for example, AspectJ is available and then include functionality for it.
We could minimize the pom at the moment but not by much; plus the big problem is that the current pom has been already published which means we have to create a new version just for the maven release which is something that I try to avoid.
I've raised an issue on JIRA: http://opensource.atlassian.com/projects/spring/browse/SJC-27 - which you can monitor.
johnlon says:
Added on October 23rd, 2007 at 4:04 pmWhat about moving JavaConfig from 'experimental' to supported status?
The comments on the javaconfig home page about status and api stability don't encourage one to invest.
I really hate XML and desparately want a full featured alternative.
Costin - Help me please!
Costin Leau (blog author) says:
Added on October 24th, 2007 at 12:54 amJohn, please raise an issue on JIRA and vote on it. JavaConfig is still on the roadmap and it's likely going to be stabilized.
Unfortunately, I cannot give you any ETAs as I personally, I'm actively working on Spring Dynamic Modules. However, note that besides JavaConfig, Spring 2.5 adds some interesting configuration options which can reduce the amount of XML one has to write.
Rod Johnson (blog author) says:
Added on November 3rd, 2007 at 8:46 pmWe are taking this project forward. Expect to see an M3 release this month.
I have just upgraded it in SVN to use the Spring Framework 2.5's new annotation scanning inside of its own (from which Spring borrowed). I have also added some support for externalization of property values, as this is a common feature request and clearly adds value, and removed some unused code to make it easier to enhance and maintain.
How long it takes to get to 1.0 final really depends on the amount of user feedback we get. There are a number of open issues in JIRA that hopefully we'll be able to fix before releasing M3, but none of them too serious.
I'm talking at QCon next week in San Francisco but ways to configure the Spring container, which should hopefully stimulate interest.
Rgds
Rod
Jeppe Cramon says:
Added on November 5th, 2007 at 7:14 amSounds really good Rod, we were getting worried that you might be dropping the project.
We've been using it with good results in our multi layered application, which features a configuration class for each layer (since many of the layers are specializations layers).
We use an inheritance scheme for the configuration classes, where a more specialized layer can override bean definitions, and it's working quite well.
/Jeppe
Jeff Wisard says:
Added on November 7th, 2007 at 1:44 pmI am also working with the java configuration and am having success with it. However, I am having difficulty with one thing. In a past iteration of my code, I have a bean defined in XML with the 'parent' attribute set to a bean imported from a different XML file. What I'd like to do is have the parent bean defined using the java configuration but keep my XML configuration of the 'child' bean that inherits the parent's definition. For example:
…
x
y
z/value>
Is this possible? Is there a trick to make it work?
Thanks!
Jeff Wisard says:
Added on November 7th, 2007 at 1:46 pmSorry, the XML that my example contained got mangled by posting. Essentially, I had a child bean defined in XML using parent="parentBean" where 'parentBean' was a bean defined using java configuration.
Costin Leau (blog author) says:
Added on November 7th, 2007 at 2:00 pmHey Jeff,
You can raise an issue on JIRA so we can brainstorm on it. JavaConfig is used for creating concrete classes rather then bean definitions (like XML). In fact, it's pretty hard (if not impossible) to determine a bean definition from a configured object so that it can be applied to a child class.
In JavaConfig, it's you who creates the object not Spring (which is what happens in XML).
Interesting use case though- please raise an issue.
Jeff Wisard says:
Added on November 7th, 2007 at 3:03 pmOkay…can you supply a link to the Jira site?
Ana says:
Added on November 15th, 2007 at 5:11 amHi,
I have a question. How can I encrypt, hide the password in jdbc.properties file?
Any suggestions?
Thanks.
Costin Leau (blog author) says:
Added on November 15th, 2007 at 5:24 amAna, please use the Spring forums (http://forum.springframework.org/) not this blog. This question has been asked before so if you search for it, you should be able to find a reasonable number of answers.
Thank you
Manri says:
Added on November 25th, 2007 at 11:45 pmHi,
great project! I really like the way Spring can be configured with JavaConfig. In my opinion it is difficult to maintain large Spring XML files especially when refactoring and the new annotation configuration of 2.5 puts too much configuration into the code.
The projects I am working on are seperated into modules each having spring configuration files in XML. Some modules depend on other modules and while I was reading the documentation and JIRA issues for JavaConfig I wondered how to configure a BeanB which depends on BeanA (which is configured in a seperate class):
// config of module A
@Configuration
public class ConfigA {
@Bean
public BeanA beanA() {
return new BeanA();
}
}
// config of module B which depends on module A
@Configuration
public class ConfigB {
@Bean
public BeanB beanB() {
BeanB beanB = new BeanB();
beanB.setBeanA(beanA()); //
I came accross the @Import annotation but I can't seem to figure out how to reference a bean configured in an imported config except by calling getBean().
Manri says:
Added on November 25th, 2007 at 11:49 pmSorry, my code has been stripped after this line:
beanB.setBeanA(beanA());
Here is the rest:
return beanB;
}
}
What I want to do is call beanA() of ConfigA.
Mike says:
Added on December 21st, 2007 at 9:42 amCostin,
Thanks for the great product.
What are your plans for M3 release? I see many cool things are coming (and some api changes). I'd like to use those, but would prefer milestone over the snapshot.
Regards,
-Mike
C.B. Diesse says:
Added on February 23rd, 2008 at 1:12 pmHi Spring team,
Rod Johnson (blog author) says:
Added on November 3rd, 2007 at 8:46 pm -Quote
We are taking this project forward. Expect to see an M3 release this month.
Have been long time since… the JavaConfig 1.0M3 was scheduled for November 2007 ! and the 1.0 release was awaited for jan 2008. Seem like JavaConfig have been given a low priority. I think many java developers are really tired about XML pseudo config language. Please release the JavaConfig or declare it out of spring future plans … So, the community can know how to plan their use of the springFramework.
Thanks for the IOC environment, but sorry for the XML, I have tried but can't really endure that … I really prefer to have annotations as first choice java component/bean/service configuration utility and use xml/properties files for user overrid-able parameters.
Please give an answer …
Claude.
Chris Beams (blog author) says:
Added on March 27th, 2008 at 1:17 am[quote comment="99211"]
Have been long time since… the JavaConfig 1.0M3 was scheduled for November 2007 !
Please give an answer …
Claude.[/quote]
Hi Claude - you're quite right to call us on this. We did say that the M3 release would come in November and didn't deliver. You'll see in my latest post (link below) that M3 has been released today. There are a number of reasons for the delay, but bottom line is that JavaConfig is supported going forward and we're committed to releasing 1.0 as soon as possible. Thanks for speaking up, and your feedback on the new milestone will be most appreciated.
http://blog.springsource.com/main/2008/03/26/spring-java-configuration-whats-new-in-m3/