具有动态位置路径的Spring属性PlaceHolder配置器

具有动态位置路径的Spring属性PlaceHolder配置器,spring,Spring,我有以下基于Spring XML的配置: <!-- These properties define the db.type property. --> <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="order" value="1"/> <property name="ignoreUn

我有以下基于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>
是否有任何方法可以使用PropertyPlaceHolderConfigure的locations属性中的属性?我希望避免使用JVM系统属性来设置db.type值

谢谢,,
Jan

这两个后处理器都是实例化的,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
    }
}

由于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 );
  }

  ...
}
公共类SpringProfilesActivator
实现ApplicationContextInitializer
{
私有静态最终记录器log=LoggerFactory.getLogger(SpringProfilesActivator.class);
...
@凌驾
public void初始化(XmlWebApplicationContext applicationContext)
{
//TODO:从某处获取您的配置文件(配置文件、JVM系统属性、数据库等)
String[]activeProfiles=新字符串[]{…};
log.info(“激活Spring配置文件:{}”,Arrays.toString(activeProfiles));
ConfigurableEnvironment=applicationContext.getEnvironment();
环境设置活动配置文件(活动配置文件);
}
...
}

谢谢你,这个主意很有趣。最后,我实现了一个自定义ApplicationContextInitializer,它根据db.type config值激活一个Spring概要文件,从而解决了这个问题。然而,这是我得到的唯一答案,因此我将答案标记为已接受。
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 );
  }

  ...
}