Spring:针对环境的配置

3

使用Spring框架时,我需要一些特定于环境(dev|test|prod)的属性。我只有一个配置文件(myapp.properties),但由于某些原因我不能拥有多个配置文件(即使Spring可以处理多个配置文件)。

因此,我需要添加带有前缀的属性的可能性,例如

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

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


3
查看配置文件。您不必在同一文件中混合使用不同的属性。您需要为每个环境准备特定的属性文件。这里有一个入门链接 - Sotirios Delimanolis
2
个人资料是一个合理的起点。如果这不能满足您的需求,我建议创建一个属性文件定位器类;例如,我们已经创建了一些基于用户和/或机器名称加载属性文件的类。 - Dave Newton
@SotiriosDelimanolis,DaveNewton:谢谢你们的建议。我会看一下个人资料。 - Emi
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(或任何其他Spring配置文件)中:

<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

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


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");

如果我需要在Spring配置中引用属性,那么这样做是行不通的。 - Emi
1
我理解你的意思,在Spring中,你应该设置:<bean id="myConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations">
<list>
<value>classpath:myapp.properties</value> </list> </property> </bean>
- sgroh

2
如果您有环境变量并希望根据此变量获取属性,可以按照以下方式声明您的属性:
<property name="username" value="${${env-target}.database.username}" />
<property name="password" value="${${env-target}.database.password}" />

同时确保您使用了正确配置的property-placeholder:

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

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

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

但是,正如之前提到的那样,最好使用配置文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接