根据配置文件在Spring中加载属性文件

时间:2012-05-19 23:00:22

标签: java spring

我有一个Spring 3.1应用程序。假设它有一个包含以下内容的XML:

<context:property-placeholder location="classpath:somename.properties" />

<context:property-placeholder location="classpath:xxx.properties" />

我希望some.properties总是被加载(让我们假设它存在),但第二个占位符的xxx部分将被某个名称替换,具体取决于活动的配置文件。我试过这个:

<beans profile="xx1">
    <context:property-placeholder location="classpath:xx1.properties" />
</beans>

<beans profile="xx2">
    <context:property-placeholder location="classpath:xx2.properties" />
</beans>

此外,两个文件都具有相同键但属性不同的属性。

但是它没有像某个后来的bean一样工作,它有一个属性的占位符,其键在xx1.properties(和xx2.properties)中定义,使得Spring抱怨在应用程序上下文中找不到该键。

2 个答案:

答案 0 :(得分:5)

你可以这样做:

  <context:property-placeholder location="classpath:${spring.profiles.active}.properties" />

它工作正常,但在同一时间使用多个配置文件时可能无法适应。


当声明2个属性占位符时,如果第一个属性占位符不包含所有应用程序键,则应该将属性忽略为unresolvable = true,以便可以使用第二个占位符。 我不确定它是否是您想要做的,如果您希望xx1和xx2配置文件同时处于活动状态,则可能会这样做。

请注意,声明这样的2个属性占位符使它们无关,并且在xx2.properties的声明中,您不能重用xx1.properties的值。


如果您需要更高级的东西,可以在应用程序启动时注册PropertySource。

的web.xml

  <context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value>
  </context-param>

你创建的文件:

public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

  private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class);

  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
    LOGGER.info("Adding some additional property sources");
    String profile = System.getProperty("spring.profiles.active");
    // ... Add property sources according to selected spring profile 
    // (note there already are some property sources registered, system properties etc)
    applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource);
  }

}

完成后,您只需添加上下文:

<context:property-placeholder/>

Imho这是处理spring属性的最佳方法,因为你不再在任何地方声明局部属性,你可以对所发生的事情进行编程控制,并且可以在xx2.properties中使用属性源xx1值。


在工作中我们正在使用它并且它工作得很好。我们注册了3个其他财产来源: - 基础设施:由Puppet提供 - 配置文件:根据配置文件加载的不同属性。 - Common:当所有配置文件共享相同的值等时,默认值包含值...

答案 1 :(得分:1)

我已决定提交并回答此问题,因为它尚未被接受。它可能不是你正在寻找的具体但它适用于我。另请注意,我正在使用新的注释驱动配置,但它可以移植到xml配置。

我有一个每个环境的属性文件(dev.properties,test.properties等)

然后我有一个RootConfig类,它是用于所有配置的类。这个类中包含的所有内容都是两个注释:@Configuration和@ComponentScan(basePackageClasses = RootConfig.class)。 这告诉它扫描与它相同的包中的任何内容。

然后有一个配置包含我所有的正常配置。对于与上面的根配置类相同的包中的每个环境,还有一个配置。

特定于环境的配置只是标记类,它具有以下注释以指向特定于环境的属性文件:

@Configuration
@PropertySource("classpath:dev.properties")
@Import(NormalConfig.class)
@Profile("dev")

导入告诉它引入正常的配置类。但当它进入那里时,它将设置特定于环境的属性。