Thursday, June 7, 2007

ApplicationContext Tricks

Part of our project is a standalone J2SE app with a good 'ol static void main. We plan to have several instances of this application running at the same time on the same server. Each instance will be configured differently as well. However, we only want to deploy one copy of the jar. We're using Spring so the issue is basically how do we initialize our ApplicationContext such that it points at the right configuration settings?


First off, we'll have application instances that require completely different Spring config files. That's easy enough we just pass in a parameter and we're done. It gets tricky where we'll need multiple app instances running off the same Spring config but with slightly different settings for some beans. For example, instance A needs a bean to point at a server on port 9000 while instance B needs the same bean to point to a different server on port 10000.


As it turns out, the solution is relatively simple:


public static void main(final String[] args) {
    String configPath = args[0];
    String propertiesPath = args[1];
    PropertyOverrideConfigurer configurer = new PropertyOverrideConfigurer();
    configurer.setLocation(new FileSystemResource(propertiesPath));
    AbstractApplicationContext context =
        new FileSystemXmlApplicationContext(new String[]{configPath}, false);

    context.addBeanFactoryPostProcessor(configurer);
    context.refresh();
    // rest of your main code
}

We make use of Spring's PropertyOverrideConfigurer which basically allows you to override property values specified in the config file with values found in a standard java properties file. Usually you would just configure this as a bean within your Spring config file. But we get sneaky and programmatically add it to our application context before the beans are initialized. This lets us choose which properties file we want to load at run time. Now we don't have to write a complete Spring config for each instance of the application we want to run. Easy as pie!

1 comment:

Justin Wilson said...

Nice! I'm gonna have to start reading your blog so it will get me to start playing around with Java again :)