Thursday, July 10, 2008

Spring Config with Zero XML

So, if you really don't want to use any XML to configure Spring and you also don't want to use the Spring JavaConfig project (create beans using Java code), you can actually use annotation-based config. I found this looking at the context:component-scan unit tests. You just create a GenericApplicationContext and a ClassPathBeanDefinitionScanner. Then call refresh on the context load the bans and register a shutdown hook so you get destruction callbacks on your beans when the JVM is shutdown. The ClassPathBeanDefinitionScanner registers the @Autowired and @Required bean post processors. It also registers the JSR-250 Commons Annotations and the PersistenceAnnotationBeanPostProcessor for JPA if their jars are in the classpath. It's pretty straightforward.

Also it could be a good way to unit test how many beans are being pick up by the context:component-scan in case you're worried you configured the packages it's scanning incorrectly.

A downside to this is that if you are using the Spring IDE in Eclipse, you won't be able to register an XML file with it. The latest version handles XML configured beans and ones that are scanned so you can get consolidated bean graphs and all the other help it provides. I personally wouldn't do this and it's worth having a very, very small XML file just to define context:component-scan directly.


String basePackage = this.getClass().getPackage().getName();

GenericApplicationContext ctx = new GenericApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(ctx);
int beanCount = scanner.scan(basePackage);

ctx.refresh();
ctx.registerShutdownHook();

2 comments:

Rossen Stoyanchev said...

Hi David, I'm always curious about requirements such as "zero XML". I can understand a personal distaste for XML but beyond that is there any rational being expressed for avoiding even minimal amounts of it?

David Winterfeldt said...

I sometimes feel that I'm one of the few people that really doesn't mind XML. :)

This was based on requirements for a software product. The reason expressed to me for "zero XML" was not wanting to expose any internal configuration to clients. I don't see how just having a context:component-scan in an XML file in the classpath is really showing anyone anything, but that was the requirement. I wanted to show them that you could use Spring configured using code along with annotation-based configuration since they were originally only evaluating Guice because of the "zero XML" requirement.