Thursday, 14 May 2009

Spring configuration - java vs XML


I came to Spring from a newbie perspective, and one of the first mystifying things thrown at you are "Add the foobar bean to the spring xml and define the necessary name and autowiring type" at which point I was already in the "I've lost you.." mode.


Spring Javaconfig reached the 1.0 release at just the right time for me to start using it in a production environment. I feel that JavaConfig is better suited than XML because:

  • While XML isnt new, every new file that a developer needs to configure adds to his work. JavaConfig being defined in Java itself, means that all a developer needs to know, is a few new annotations.
  • Java files support better IDE integration. Which means that you can click on the files from which the ContextConfiguration is loaded, and look at what beans that class provides. This click-and-navigate only seems to be work in Eclipse (3.4) and not Netbeans at this point.
  • Extending from the previous point, a java method implementation allows you to control the bean scope better. The method implementation can either be
  • FactoryMethod.getInstance() //singleton instance
  • FactoryMethod.createNew() or even //factory creating a bean
  • new FooBar() //just a new.Note: If there are @autowired  dependencies here, you need AOP.

In this case, as long as the Spring application context simply calls a method with the @Bean annotation, it can leave the scope (singleton|prototype) etc to the method itself. Unfortunately, JavaConfig has to be backwards-compatible (with the XML construct <bean>) and the scope (if prototype) needs to be provided. Perhaps later releases of JavaConfig could make the default bean scope non-singleton.

What JavaConfig can improve upon:

  • The initialization and actual wiring happens at run time rather compile time, which is good. However, this means that they typical two problems with wiring, one that there is no bean available, or that there are multiple beans available, are discovered at runtime. Since beans are lazily initialized, the first successful run of a test happens only after all the bean wiring problems are sorted out. Also, the bean wiring exceptions are seen one after another, rather than all at once.
  • The error messages about bean wiring could be better. They are often at the tail end of a long stack trace and are sometimes difficult to decipher.
  • Click-through support in an IDE for ContextConfiguration is good. However, there is no way in an IDE to navigate from an @Autowired bean to the class that provides the bean, and vice versa. This problem gets compounded when the number of tests increase. Each @Autowired bean usually as multiple (bean) configurations to borrow from, and this process has to be done manually. Some of these are listed in the JIRA ticket list for SJC.

Reasons why you might still need XML configuration:

  • Configuring load-time weaving with the <context:load-time-weaver/> needs to be mentioned in XML. There is a proposed annotation to handle this requirement, though.

As a sidebar, you might want to check the difference in the DI styles of Spring vs Guice. Although Spring Javaconfig is supposed to have borrowed ideas from Guice, its not immediately apparent. Guice uses a fluent builder to define the configuration as opposed to POJO in the Spring way.




1 comment:

Dinesh Kumar said...

Apart from no bean and multiple bean issue, another bean issue is "transitive bean dependency". For example, if bean A is dependent on bean B then while declaring bean A, bean B should also be declared otherwise NO BEAN DEFINITION FOUND exception will be thrown. It also increases the tedious work of finding undeclared bean when bean B is developped by some other developper and you are a developper of bean A