Wednesday, May 25, 2011

Loading Spring Beans based on environment

In complex deployment environments it makes sense to keep web application monolith war file and provide appropriate instructions for deployment team. It's possible only if your application have flexible configurability strategy, so that at least you can switch from DEV to UAT, from UAT to PROD environments and be sure that only thing has been changed is environment specific stuff. Forget about unpacking and patching war-file, it could be prohibited at all because of non-trivial distribution mechanism.

For Spring-based applications all this could look a little bit scary for a first look, you have your applicationContext.xml with placeholders, which is ok, or JNDI for enviromnent-specific resource lookup. Great, but what you are going to do if some of the parts of resources are present in one env. and absent in another ? For example +1 in dev, -1 in uat and +1 in prod ? Maybe there is not only one way to do it, but I came across the following solution for this.

It's based on combination of servlet context init params and Spring bean re-definition at runtume. Thanks to Spring it's possible. In terms of configurability servlet init params is very flexible thing. You can define one in web.xml, and then redefine it in context setup. I mean externally, so, your war file is still don't need to be patched. Other stuff is technical details for this - key point to implement this is Spring bean which implements both ServletContextAware and ApplicationContextAware interfaces. First makes possible to access Servlet context, second - Spring application context. Runtime re-defintion is not so hard - take a look here.

Complete source code you can find here.