账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    [Spring] 多个 PropertyPlaceholderConfigurer 导致占位符未替换问题
    33
    0

    这是一个 Spring 项目,
    第一个 PropertyPlaceholderConfigurer ,在 context-aaa.xml 主要是配置 JDBC properties

    
        <bean id="jdbcPropertyPlaceholder"
              class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="order" value="0"/>
            <property name="ignoreUnresolvablePlaceholders" value="true"/>
            <property name="location">
                <value>classpath:jdbc.properties</value>
            </property>
        </bean>
        

    其中,jdbc.properties 的内容如下:

    test.datasource.url=jdbc:mysql://192.168.0.66:3306/dev
    test.datasource.username=root
    test.datasource.password=123456

    第二个 PropertyPlaceholderConfigurer ,在 context-bbb.xml ,功能是从数据里加载 properties

    
        <bean id="commonsConfigurationPropertyPlaceholder"
              class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="order" value="1"/>
            <property name="ignoreUnresolvablePlaceholders" value="true"/>
            <property name="properties" ref="commonsConfigurationFactoryBean"/>
        </bean>
    
        <bean name="commonsConfigurationFactoryBean"
              class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
            <constructor-arg ref="configuration"/>
        </bean>
        
        <bean id="configuration" class="org.apache.commons.configuration.DatabaseConfiguration">
            <constructor-arg type="javax.sql.DataSource" ref="druidDataSource"/>
            <constructor-arg index="1" value="configuration"/>
            <constructor-arg index="2" value="name"/>
            <constructor-arg index="3" value="value"/>
        </bean>
                    
    
        <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="url"      value="${test.datasource.url}"/>
            <property name="username" value="${test.datasource.username}"/>
            <property name="password" value="${test.datasource.password}"/>
        </bean>
    

    问题来了,加载 DruidDataSource 时,占位符并没有被替换。

    我已经加了 PropertyPlaceholderConfigurer 的 order 属性排序,以及 ignoreUnresolvablePlaceholders 为 true 了,但是问题依旧。

    DruidDataSource 作为第二个 PropertyPlaceholderConfigurer 的依赖,它的配置占位符不会被处理吗?
    我断点发现,BeanFactoryPostProcessor 的处理,在程序的报错之后才执行,是怎么回事?

    https://jira.spring.io/browse...

    我找到了解决方案:
    The alternative is to

    (a) use the new PropertySourcesPlaceholderConfigurer instead of the traditional PropertyPlaceholderConfigurer;

    (b) eliminate the first PropertySourcesPlaceholderConfigurer ;

    (c) register a PropertySource with the ApplicationContext's Environment that contains the properties for the placeholders that need replacement in the PropertySourcesPlaceholderConfigurer

    我想问第三步怎么操作啊?

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 在Spring框架中,PropertyPlaceholderConfigurer是一个Bean后处理器,用于从属性文件中解析和替换Bean定义中的占位符(placeholder)。然而,如果在同一个Spring容器中配置了多个PropertyPlaceholderConfigurer,可能会出现占位符未替换的问题。

      这是因为当存在多个PropertyPlaceholderConfigurer时,Spring容器会按顺序处理它们。第一个处理器会替换它能找到的所有占位符,而后续的处理器可能无法找到需要替换的占位符,因为它们已经被前面的处理器处理过了,或者它们查找的属性文件中没有对应的键值对。

      解决办法:

      1. 合并属性源:尽量在一个PropertyPlaceholderConfigurer中加载所有需要的属性文件,避免使用多个处理器。

      xml <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config.properties</value> <value>classpath:db.properties</value> </list> </property> </bean>

      1. 优先级设置:若确实需要使用多个处理器,并且有优先级关系,可以考虑通过设置order属性来控制它们的执行顺序。

      2. 使用Environment@Value注解:在Spring 3.1及以上版本中,推荐使用@Configuration类结合@PropertySource以及@Value注解进行属性注入,这种方式更为灵活且不会遇到上述问题。

      ```java @Configuration @PropertySource("classpath:config.properties") public class AppConfig {

      @Autowired
      private Environment env;
      
      @Value("${property.name}")
      private String propertyName;
      

      } ```

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部