简体   繁体   中英

How do I provide external application context configuration properties?

I have a web application which uses external configuration file containing some sort of properties which is loaded just before application context is loaded:

public class StartupListener
        extends org.springframework.web.context.ContextLoaderListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        com.acme.app.Configuration configuration
                = com.acme.app.Configuration.loadFromFile("C:/config.xml");
        // String dbUser = configuration.getDatabaseConfig().getUser();
        // String dbPassword = configuration.getDatabaseConfig().getPassword();

        super.contextInitialized(event);
    }

}

C:\\config.xml:

<config xmlns="http://www.acme.com/app/config">
    ...
    <databaseConfig>
        <user>...</user>
        <password>...</password>
    </databaseConfig>
    ...
</config>

web.xml:

<web-app ...>
    ...
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    ...
    <listener>
        <listener-class>com.acme.app.StartupListener</listener-class>
    </listener>
    ...
</web-app>

applicationContext.xml:

<beans ...>
    ...
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        ...
        <property name="username" value="${db.user}"/>
        <property name="password" value="${db.password}"/>
        ...
    </bean>
    ...
</beans>

I want to push ${db.user} and ${db.password} properties into the context just after they became available:

com.acme.app.Configuration configuration
        = com.acme.app.Configuration.loadFromFile("C:/config.xml");
String dbUser = configuration.getDatabaseConfig().getUser();
String dbPassword = configuration.getDatabaseConfig().getPassword();

But I only know just two ways of doing this:

1) creating one more configuration file as .properties file:

C:\\anotherConfig.properties:

db.user=...
db.password=...

applicationContext.xml:

<beans ...>
    ...
    <context:property-placeholder location="file:C:/anotherConfig.properties"/>
    ...
</beans>

2) or adding properties to the system properties:

System.setProperty("db.user",
        configuration.getDatabaseConfig().getUser());
System.setProperty("db.password",
        configuration.getDatabaseConfig().getPassword());

Both looks bad for me (especially first one).

Is there are any ways of doing this more Spring-like? Maybe like this:

public class MyPropertiesProvider
        implements org.springframework.foo.bar.PropertiesProvider {

    @Override
    public Properties getProperties() {
        Properties properties = new Properties();
        com.acme.app.Configuration configuration
                = com.acme.app.Configuration.loadFromFile("C:/config.xml");
        properties.setProperty("db.user",
                configuration.getDatabaseConfig().getUser());
        properties.setProperty("db.password",
                configuration.getDatabaseConfig().getPassword());
        return properties;
    }

}

applicationContext.xml:

<beans ...>
    ...
    <context:property-placeholder-provider ref="myPropertiesProvider"/>
    <bean id="myPropertiesProvider" class="com.acme.app.MyPropertiesProvider"/>
    ...
</beans>
  • Create a property file for each environment
  • Include all environments in your deployment archive (Maven assembly plugin can do this for you),
  • Create a deployment script so you can run all setup with a single argument (the target environment) and have the coordinate moving the right configuration to the correct target location in each folder (or run application server CLI, or push database changes, whatever you need)
  • Configure your continuous delivery system to run the deploy script after copying your artifact with the right argument for the target environment.

To help with generating properties, config, scripts etc take a look at this plugin available on Maven Central: https://github.com/sofdes/config-generation-maven-plugin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM