3

使用 Spring 我需要某种环境 (dev|test|prod) 特定属性。

我只有一个配置文件(myapp.properties),由于某些原因,我不能拥有多个配置文件(即使 spring 可以处理多个)。

所以我需要添加带有前缀的属性的可能性

dev.db.user=foo
prod.db.user=foo

并告诉应用程序将哪个前缀(环境)与类似-Denv-target或类似的 VM 参数一起使用。

4

3 回答 3

5

我为此目的使用了一个子类PropertyPlaceholderConfigurer

public class EnvironmentPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

    private static final String ENVIRONMENT_NAME = "targetEnvironment";

    private String environment;

    public EnvironmentPropertyPlaceholderConfigurer() {
        super();
        String env = resolveSystemProperty(ENVIRONMENT_NAME);
        if (StringUtils.isNotEmpty(env)) {
            environment = env;
        }
    }

    @Override
    protected String resolvePlaceholder(String placeholder, Properties props) {
        if (environment != null) {
            String value = props.getProperty(String.format("%s.%s", environment, placeholder));
            if (value != null) {
                return value;
            }
        }
        return super.resolvePlaceholder(placeholder, props);
    }

}

并在applicationContext.xml(或任何其他弹簧配置文件)中使用它:

<bean id="propertyPlaceholder"class="EnvironmentPropertyPlaceholderConfigurer">
    <property name="location" value="classpath:my.properties" />
</bean>

my.properties您可以定义如下属性:

db.driverClassName=org.mariadb.jdbc.Driver
db.url=jdbc:mysql:///MyDB
db.username=user
db.password=secret
prod.db.username=prod-user
prod.db.password=verysecret
test.db.password=notsosecret

因此,您可以通过环境键(例如prod)为属性键添加前缀。

使用 vm 参数targetEnvironment,您可以选择您喜欢使用的环境,例如-DtargetEnvironment=prod.

如果不存在特定于环境的属性,则选择默认的(不带前缀)。(您应该始终定义一个默认值。)

于 2013-08-21T20:32:17.293 回答
2

如果你有环境变量并且想根据这个变量获取属性,你可以这样声明你的属性:

<property name="username" value="${${env-target}.database.username}" />
<property name="password" value="${${env-target}.database.password}" />

还要确保您使用正确配置的属性占位符:

<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>

或者,如果您使用特殊的属性配置器(例如 EncryptablePropertyPlaceholderConfigurer),请设置属性:

<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />

但如前所述,最好使用配置文件。

于 2013-08-15T12:43:31.947 回答
2

我不知道避免拥有多个配置文件的限制是什么,但您可以使用 -Denvtarget=someValue 之类的东西,并在 java 中执行以下操作:

//Obtain the value set in the VM argument 
String envTarget= System.getProperty("env-target");

Properties properties;
try {
   properties = PropertiesLoaderUtils.loadAllProperties("myapp.properties");
} catch (IOException exception) {
  //log here that the property file does not exist.    
}

//use here the prefix set in the VM argument.
String dbUser = properties.getProperty(envTarget+".db.user");
于 2013-08-14T20:48:20.937 回答