我有以下基于Spring XML的配置:
<!--
These properties define the db.type property.
-->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="order" value="1"/>
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- contains default db.type -->
<value>classpath:/default-cfg.properties</value>
<!-- db.type can be overridden by optional properties in the app work dir -->
<value>file:${app.work.dir}/cfg.properties</value>
</list>
</property>
</bean>
<!-- db.type should be used to get DB specific config properties -->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="order" value="2"/>
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="ignoreResourceNotFound" value="false" />
<property name="locations">
<list>
<!-- does not work, ${db.type} does not get resolved -->
<value>classpath:/default-cfg-${db.type}.properties</value>
</list>
</property>
</bean>
问题是,即使第一个属性占位符配置器定义了classpath:/default-cfg-${db.type}.properties
,db.type
位置中的属性也无法解析。
我在日志中不断收到以下错误:
class path resource [default-cfg-${db.type}.properties] cannot be opened because it does not exist
有没有办法在PropertyPlaceholderConfigurer的locations属性中使用属性?我想避免使用JVM系统属性来设置db.type值。
谢谢你, 扬
答案 0 :(得分:2)
由于Alireza Fattahi要求我的代码和WornOutSoles建议接受的解决方案无法正常工作,我发布了基于Spring ApplicationContextInitializer的最终解决方案:
public class SpringProfilesActivator
implements ApplicationContextInitializer<XmlWebApplicationContext>
{
private static final Logger log = LoggerFactory.getLogger( SpringProfilesActivator.class );
...
@Override
public void initialize( XmlWebApplicationContext applicationContext )
{
// TODO: get your profiles from somewhere (config files, JVM system properties, database etc.)
String[] activeProfiles = new String[] { ... };
log.info( "Activating Spring profiles: {}", Arrays.toString( activeProfiles ) );
ConfigurableEnvironment env = applicationContext.getEnvironment();
env.setActiveProfiles( activeProfiles );
}
...
}
答案 1 :(得分:0)
两个后处理器都被实例化,orderer然后执行,因此第二个PSPC
在第一个PSPC
被执行之前被实例化。
如果您的第一个BeanDefinitionRegistryPostProcessor
实现public class BeanDefinitionRegistryPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer
implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// nothing todo, just to run before other PPHCs are instantiated
}
}
将在第二个实例化之前运行,并且可以按预期工作。
例如:
{{1}}