前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中PropertyPlaceholderConfigurer替换占位符的问题

Spring中PropertyPlaceholderConfigurer替换占位符的问题

作者头像
石臻臻的杂货铺[同名公众号]
发布2021-07-14 10:04:16
1.3K0
发布2021-07-14 10:04:16
举报
文章被收录于专栏:kafka专栏

最近在做项目的时候,碰到了一个问题,纠结了好久,现在记录一下

问题

多个Maven项目聚合的时候,每个maven都有自己的配置文件,并且都用了PropertyPlaceholderConfigurer替换占位符,然后启动的时候一直报错,说替换失败;问题症结就是 spirng配置多个PropertyPlaceholderConfigurer的问题

原因

在spring bean装配时,一个PropertyPlaceholderConfigurer就是一个后置处理器BeanFactoryPostProcessor。在装配完PropertyPlaceholderConfigurer之后,就会触发org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(Collection, ConfigurableListableBeanFactory)方法,代码如下:

代码语言:javascript
复制
/**
 * Invoke the given BeanFactoryPostProcessor beans.
 */
private void invokeBeanFactoryPostProcessors(
        Collection postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

假设一下,你配置了两个PropertyPlaceholderConfigurer实例 A模板的jdbc.xml配置文件

代码语言:javascript
复制
<bean id="propertyConfigurer" class="com.zheng.common.plugin.EncryptPropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.propertiesvalue>
                <value>classpath:redis.propertiesvalue>
            list>
        property>
    bean>

B模板的shiro.xml配置文件

代码语言:javascript
复制
    <context:property-placeholder location="classpath*:zheng-upms-client.properties"/>

然后A模板中的jdbc.properties 和 B中的zheng-upms-client.properties 文件都在A模板中; A依赖了B;启动A项目,IOC会先实例化这两个配置的PropertyPlaceholderConfigurer; 假如先实例化了A中的PropertyPlaceholderConfigurer实例,那么它会去替换所有被标记为 ${} 的占位符,这个时候替换到B模板中的一些占位符之后,肯定就会报错了,因为B模板中的占位符是在 zheng-upms-client.properties这个属性文件中;

解决方案

一、使用一个PropertyPlaceholderConfigurer实例加载

代码语言:javascript
复制
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.propertiesvalue>
                <value>classpath:redis.propertiesvalue>
                 <value>classpath:zheng-upms-client.propertiesvalue>
            list>
        property>
    bean>

但是这样解决真的是超级没有诚意了,本来就是解决不通模块之间的问题啊

二、配置加载顺序,并设置替换失败不报错

1.让B中的实例配置order=1 先加载,并且设置ignore-unresolvable="true"表示替换失败不报错

代码语言:javascript
复制
    <context:property-placeholder order="1" ignore-unresolvable="true" location="classpath*:zheng-upms-client.properties"/>

2.设置A中,order=2 表示后加载,但是不设置ignore-unresolvable属性,因为最后还是要检查是否有剩余未替换的属性

代码语言:javascript
复制
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="order" value="2" />
        <property name="locations">
            <list>
                <value>classpath:jdbc.propertiesvalue>
                <value>classpath:redis.propertiesvalue>
            list>
        property>
    bean>

总结

思路就是 当有多个实例的时候,让他们一个一个的去替换,替换失败不提示错误,等做后一个实例替换的时候如果还有没有被替换的就提示错误! 所以要设置 order 来排序,因为必须让最后一个加载的去检查替换错误,之前的都可以不用检查

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/06/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 原因
  • 解决方案
  • 一、使用一个PropertyPlaceholderConfigurer实例加载
  • 二、配置加载顺序,并设置替换失败不报错
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档