Rectangle 27 1

java Import Spring config file based on property in .properties file?


Does somebody have a working example of that ? Couldn't make it work with 3.1.1.

For the Spring 2.5 and 3.0, I have a similar solution to louis, however I've just read about 3.1's upcoming feature: property management, which sounds great too.

Note
Rectangle 27 1

java Import Spring config file based on property in .properties file?


I've been lobbying to have SPR-1358 reopened, but no response so far. Perhaps if others added their use cases to the issue comments that would help raise awareness.

There is an old issue on the Spring JIRA for adding properties placeholder support for import (SPR-1358) that was resolved as "Won't Fix", but there has since been a proposed solution using an EagerPropertyPlaceholderConfigurer.

Note
Rectangle 27 1

java Import Spring config file based on property in .properties file?


public class Bootstrapper implements ApplicationContextAware, InitializingBean {

    private WebApplicationContext context;
    private String[] configLocations;
    private String[] testConfigLocations;
    private boolean loadTestConfigurations;

    public void setConfigLocations(final String[] configLocations) {
        this.configLocations = configLocations;
    }

    public void setTestConfigLocations(final String[] testConfigLocations) {
        this.testConfigLocations = testConfigLocations;
    }

    public void setLoadTestConfigurations(final boolean loadTestConfigurations) {
        this.loadTestConfigurations = loadTestConfigurations;
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        context = (WebApplicationContext) applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String[] configsToLoad = configLocations;

        if (loadTestConfigurations) {
            configsToLoad = new String[configLocations.length + testConfigLocations.length];
            arraycopy(configLocations, 0, configsToLoad, 0, configLocations.length);
            arraycopy(testConfigLocations, 0, configsToLoad, configLocations.length, testConfigLocations.length);
        }

        context.setConfigLocations(configsToLoad);
        context.refresh();
    }
}

Basically, get the application context, set its config locations, and tell it to refresh itself. This works perfectly in my application.

I don't think you need any control other than being able to tell the EJB which spring context to load. Am I missing something?

I would agree with Sean. @Louis smart stuff indeed.

I'm surprised this solution wasn't accepted. It's simple and brilliant

Note: This code was taken from a working system, but I scrubbed it manually of some small bits and pieces related to the system itself. Apologize if there are any errors.

Thanks, but unfortunately I don't have complete control of the startup as an EJB is the entrypoint to the application. Maybe I should just upgrade to Spring 3 and use the JavaConfig instead :)

This is, unfortunately, a lot harder than it should be. In my application I accomplished this by doing the following:

This works because the context files are specified as input the the bean responsible for loading them. It won't work if you just try to do an import, as you mentioned, but this has the same effect with slightly more work. The bootstrap class looks something like this:

Note
Rectangle 27 1

java Import Spring config file based on property in .properties file?


  • whichever Spring config is loaded sets specific stuff, then loads a common Spring config

The entrypoint to the application is an EJB which loads the ApplicationContext on the first method call, so I can't really do what you're suggesting.

Note
Rectangle 27 1

java Import Spring config file based on property in .properties file?


Another means that might be of use are XML entities (defined by adding <!ENTITY ... > elements into the DTD declaration at the beginning of XML). These allow importing XML fragments from other files and provide "property placeholder"-like functionality for any XML file.

If what you want is to specify the imported XML file name outside applicationContext.xml so that you could replace applicationContext.xml without losing the configuration of the imported XML file path, you can just add an intermediate Spring beans XML file, say, confSelector.xml, so that applicationContext.xml imports confSelector.xml and confSelector.xml only contains an <import> element that refers to the suitable custom beans XML file.

Neither of these solutions allows you to have the configuration file in Java's .properties format, though.

Note