Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 217 posts at DZone. You can read more from them at their website. View Full User Profile

Consider replacing Spring XML configuration with JavaConfig

03.10.2013
| 27139 views |
  • submit to reddit
Spring articles are becoming a trend on this blog, I should probably apply for a SpringSource position :-)

Colleagues of mine sometimes curse me for my stubbornness in using XML configuration for Spring. Yes, it seems so 2000′s but XML has definite advantages:

  1. Configuration is centralized, it’s not scattered among all different components so you can have a nice overview of beans and their wirings in a single place
  2. If you need to split your files, no problem, Spring let you do that. It then reassembles them at runtime through internal <import> tags or external context files aggregation
  3. Only XML configuration allows for explicit wiring – as opposed to autowiring. Sometimes, the latter is a bit too magical for my own taste. Its apparent simplicity hides real complexity: not only do we need to switch between by-type and by-name autowiring, but more importantly, the strategy for choosing the relevant bean among all eligible ones escapes but the more seasoned Spring developers. Profiles seem to make this easier, but is relatively new and is known to few
  4. Last but not least, XML is completely orthogonal to the Java file: there’s no coupling between the 2 so that the class can be used in more than one context with different configurations

The sole problem with XML is that you have to wait until runtime to discover typos in a bean or some other stupid boo-boo. On the other side, using Spring IDE plugin (or the integrated Spring Tools Suite) definitely can help you there.

An interesting alternative to both XML and direct annotations on bean classes is JavaConfig, a former separate project embedded into Spring itself since v3.0. It merges XML decoupling advantage with Java compile-time checks. JavaConfig can be seen as the XML file equivalent, only written in Java. The whole documentation is of course available online, but this article will just let you kickstart using JavaConfig. As an example, let us migrate from the following XML file to a JavaConfig

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
 
    <bean id="button" class="javax.swing.JButton">
        <constructor-arg value="Hello World" />
    </bean>
 
    <bean id="anotherButton" class="javax.swing.JButton">
        <property name="icon" ref="icon" />
    </bean>
 
    <bean id="icon" class="javax.swing.ImageIcon">
        <constructor-arg>
            <bean class="java.net.URL">
              <constructor-arg value="http://morevaadin.com/assets/images/learning_vaadin_cover.png" />
            </bean>
        </constructor-arg>
    </bean>
</beans>
The equivalent file is the following:
import java.net.MalformedURLException;
import java.net.URL;
 
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class MigratedConfiguration {
 
    @Bean
    public JButton button() {
 
        return new JButton("Hello World");
    }
 
    @Bean
    public JButton anotherButton() {
 
        return new JButton(icon());
    }
 
    @Bean
    public Icon icon() throws MalformedURLException {
 
        URL url = new URL("http://morevaadin.com/assets/images/learning_vaadin_cover.png");
 
        return new ImageIcon(url);
    }
}

Usage is simpler than simple: annotate the main class with @Configuration and individual producer methods with @Bean. The only drawback, IMHO, is that it uses autowiring. Apart from that, It just works.

Note that in a Web environment, the web deployment descriptor should be updated with the following lines:

<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.packtpub.learnvaadin.springintegration.SpringIntegrationConfiguration</param-value>
</context-param>

Sources for this article are available in Maven/Eclipse format here.

To go further:

  • Java-based container configuration documentation
  • AnnotationConfigWebApplicationContext JavaDoc
  • @ContextConfiguration JavaDoc (to configure Spring Test to use JavaConfig)
Published at DZone with permission of Nicolas Frankel, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Andreas Schilling replied on Sun, 2013/03/10 - 4:26pm

 I also definitely favor xml over annotations for several reasons:

  • well structured xml provides an immediate overview of what beans exist and how they are wired, at least if you're a little used to reading spring configs
  • annotations quickly get out of control. sometimes I see classes and methods with 4+ lines of annotations. not so nice.
  • annotations are very dense in the sense of what information they give about what they are doing. while this can be appealing and nice (@Transactional for example) sometimes it just makes things terribly hard to read. this is more of a general thing, not necessarily valid for the majority of the spring annotations

matt inger replied on Sun, 2013/03/10 - 8:03pm

There's nothing in your @Configuration which *requires* autowiring.  You could just as easily have done this

@Bean
public JButton anotherButton() {
    return new JButton(icon());
}

Autowiring is an option, and you're not required to use it.  Spring itself takes care of the magic when you call "icon()" it actually modifies your class (using cglib) so that any calls to the method (even internal ones) follow spring bean semantics (scope, initialization, etc...)


Eric Buléon replied on Mon, 2013/03/18 - 9:15am

I use AOP for run-time injection of dependencies into @Configurable objects. Is it possible to do it in Java (without XML) ? Currently I use this in my @Configuration bean:

@ImportResource("classpath:/spring-configured.xml")

where the "spring-configured.xml" file contains only the <context:spring-configured/> tag:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">

   <context:spring-configured/>

</beans>


Rodney Barbati replied on Mon, 2013/03/18 - 5:47pm

I don't know, you better be careful.  Just another step and those beans are going to become classes - and then where would we be?

I never really got the Spring thingy - so you remove the dependencies in your code to some other file and language format and everything is like "Oh, that is so cool!".  I'm like, yeah, it's really great, now I can't see a class diagram, a sequence diagram, no code analysis tools work, etc.  

And I still have to change the dependencies when the dependencies change - gosh - that is truly awesome.

And since you still have to rebuild and redeploy to see any changes you have made to these dependencies I don't see any gain over what you get by simply having a decent design to begin with.  That's right, I'm sticking with my old ItsSimplyAPOJOClassThatHasAFewMembersInItButImplementsAnInterface.

Maybe by next year, we can have invisible code editors.

On the other hand, give me a full blown spring bean editor gui with proper analysis tools, bean building with picklists and all the other bells and whistles you might expect from a mature standard that has been around for a good long while, and I might jump on the bandwagon.


Daybreaker Gijane replied on Fri, 2013/08/16 - 6:43pm in response to: Rodney Barbati

Its not a bandwagon. Its a really useful framework with well designed extension projects - not a strait-jacket - and is part of a sensible way to develop great software.

JBoss, GIT, Maven, Spring/Security, JUnit, Mockito, Commons, Guava, Java itself (even Eclipse and VirtualBox deserve a mention) are now coming of age and finally providing a comprehensive toolbox, allowing us collaborate on reliable, large scale systems that can have a myriad of features without the complexity bloat that brings down many projects.

Arjun Dhar replied on Mon, 2014/03/24 - 7:33am

I def favor XML for all valid reasons mentioned.

In addition, I also feel when developing base platforms and products; one needs to be less married to the application code itself.

XML & Scripting are the only two ways you can be less committed and flexible.

While both have their own use cases; in terms of pure DI XML is a win.

I am a little concerned @ the release of Spring-Boot where "NO XML Needed" is advertised as something as a progression. Seeing that worries me a little; though I need to fully dive in to address and understand why that is so.

If anyone has any insight on Spring-Boot and their abstinence from XML. Please enlighten me on the reasons. 

Srikanth Nair replied on Thu, 2014/04/17 - 9:19am

Spring guys doing too much of over engineering, the best example is java based config. I'm working in spring framework since 7 years and always admire each and every tech they put into spring stack but i feel java config is the useless one from spring. Open for a debate i feel spring XML configuration is far better  than java config due to

1) Readability 

2) Easy of use

3) Maintainability 

Java config is not adding any value over xml configuration other than annotation hell. 

Spring team could worked on something else rather than spending time for this useless one, like If we see all these configurations whether its XML or Java there are so many things are common irrespective of application (boilerplate) they could workout some solution for it. The second thing is, if they see advantages over xml config they could give a tool to convert xml config to java config at least in STS.

If you are in favor of Java config, you can high light its advantages as follows.

Java – no more XML!! 

benefits of Java type-safety and IDE support

Typos generate compile-error – no more waiting till load time to find XML typos

IDE refactoring tools will automatically update JavaConfig because it is regular Java

IDE automatic import feature can be used instead of typing fully-qualified class names in XML

IDE drill-down feature

IDE auto-complete feature

I don't know in which world are we, eclipse IDE support the same with xml config except only one point some times we wont get to know if anything is wrong in xml until we load the application context. Maven (xml) shortcomings leads to Gradle (groovy) (wonderful), but Java config adding nothing over XML.

Something deep sh*t is going inside spring due to geek overloaded with groovy sh*t inside, its started with Spring ROO. At the same time best hopes like Gradle and Grails. 

The basic principle of software engineering is missing KISS. 


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.