我有一个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抱怨在应用程序上下文中找不到该键。
答案 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")
导入告诉它引入正常的配置类。但当它进入那里时,它将设置特定于环境的属性。