4

我有一个 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 抱怨在应用程序上下文中找不到该键。

4

2 回答 2

9

你可以做:

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

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


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

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


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

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/>

恕我直言,这是处理 spring 属性的最佳方式,因为您不再在任何地方声明本地属性,您可以对正在发生的事情进行编程控制,并且可以在 xx2.properties 中使用属性源 xx1 值。


在工作中,我们正在使用它,它运行良好。我们注册了 3 个额外的属性来源: - 基础设施:由 Puppet 提供 - 配置文件:根据配置文件加载的不同属性。- 通用:包含默认值,当所有配置文件共享相同的值等...

于 2012-12-25T11:12:00.773 回答
2

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

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

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

然后有一个包含我所有正常配置的配置坐在任何地方。与上面的根配置类在同一个包中也有针对每个环境的配置。

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

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

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

于 2015-03-01T17:33:23.357 回答