First, off, I have to admit that I am not a XML hater. Sure, it’s not the prettiest structured data language, but it seems to do the job just fine, especially in environments where you aren’t concerned about byte size (like, say, when you are configuring a software system). Plus, it allows you comments, which some alternatives ([cough] JSON) don’t.
But, I come to contrast two types of Spring configuration, not bury XML or @Annotations. I’ve been working on a project that uses Spring annotations. I evaluated Guice, but it didn’t have lifecycle management, and we needed that. I also evaluated PicoContainer (I know, blast from the past, right) but it didn’t seem functional and the web presence was a mess. In the past, I’ve used XML based configuration of Spring. I thought it would be useful for me to capture a few of the differences.
First of all though, they are fairly similar. Both use the standard Spring workflow of “create a number of components, pass them to other components, pass those to other components, occasionally use some of the extensive spring library in a way that appears magical at times, create a few more components, and string them all together to build a system that does what you want”, whether “what you want” is responding to web requests, modifying databases, pulling data off of a queue for processing, or something entirely different.
For annotation based configuration, you are writing the configuration in classes that are specially tagged with a
@Configuration annotation. These configuration classes look for components in a couple of places, either under them in the classpath or in certain packages, as specified by the
@ComponentScan annotation. This means that you get all the benefits of your IDE:
- You get code completion.
- The compiler checks your types so that you don’t have runtime exceptions if you passed a
Foobean to a class that was expecting a
- You can do logic in the configuration class to load different components based on anything (accessing a buildtime constant, a file, a database, an external service, etc)
- You can refactor bean definitions and know that they’re changed everywhere.
All this power comes with the risk of complexity. If you read from a database table to know what kind of component implements a certain interface, that can be, shall we say, less than obvious.
XML based configuration, in my experience, is simpler. You still can have multiple layers of XML files, but you can’t have any logic, at least without using XSLT and generating your Spring configuration files (if you are doing that, annotation based configuration is going to be far simpler!). Components can be anywhere because they are specified by the fully qualified class name. XML configuration removes temptation to invoke any java code as part of your component configuration. On the flip side, you do have risk of runtime errors with typos, and you must deal with XML.
Both of these configuration options are well supported. I find that there’s more documentation online about the XML based configuration, but they are isomorphic, so I’d recommend picking the option that suits your needs best. If you need complex configuration or want the blanket of type safety, then annotation based configuration is the best option. If you have a simpler project, especially if everything can be contained in one XML file, XML based configuration is the better option.