当前位置: 首页 > article >正文

Spring PropertyPlaceholderConfigurer多配置问题

本文重点是通过例子代码的debug了解PropertyPlaceholderConfigurer的原理

更多可阅读:placeholderconfigurer文档 了解

目录

    • 测试程序如下
    • PropertyPlaceholderConfigurer
      • placeholderConfigurer1 & placeholderConfigurer2的执行
      • userbean的BeanDefinition应用PropertyPlaceholderConfigurer前:
      • userbean的BeanDefinition应用PropertyPlaceholderConfigurer后:
    • userBean的name的set
    • 总结

测试程序如下

public class TestPropertyPlaceholderConfigurer {
    public static void main(String[] args) throws Exception{
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("application.xml");
        UserBean userBean = (UserBean) applicationContext.getBean("userBean");
        System.out.println(userBean.getName());
    }
}

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="placeholderConfigurer1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="order" value="1"/>
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="locations">
            <list>
                <value>classpath:app1.properties</value>
            </list>
        </property>
    </bean>

    <bean id="placeholderConfigurer2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="order" value="2"/>
        <property name="locations">
            <list>
                <value>classpath:app2.properties</value>
            </list>
        </property>
    </bean>

    <bean name="userBean" class="com.example.demoapi.test.UserBean">
        <property name="name" value="${app.name}"/>
    </bean>


</beans>

app1.properties:

app.name=v1

app2.properties:

app.name=v2

userBean

public class UserBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

改变优先级输出的不同:

在这里插入图片描述

PropertyPlaceholderConfigurer

类图如下:
在这里插入图片描述
可以看到是个BeanFactoryPostProcessor 且实现了顺序的;回顾ApplicationContext的refresh方法之invokeBeanFactoryPostProcessors,可以知晓执行这些BeanFactoryPostProcessor是有先后次序的。- - - 顺带复习:AnnotationConfigApplicationContext流程看@Configuration,@ComponentScan,@Import等的处理

placeholderConfigurer1 & placeholderConfigurer2的执行

上述placeholderConfigurer1,placeholderConfigurer2两个bean在invokeBeanFactoryPostProcessors的如下地方完成了实例化
在这里插入图片描述
这两个实例化出来的PropertyPlaceholderConfigurer接着排序
在这里插入图片描述

接着执行调用bfpp的postProcessBeanFactory方法
org.springframework.beans.factory.config.PropertyResourceConfigurer#postProcessBeanFactory
在这里插入图片描述
构造placeholderConfigurer2的PlaceholderResolvingStringValueResolver,然后进行beanDefinition合并操作

org.springframework.beans.factory.config.PlaceholderConfigurerSupport#doProcessProperties
在这里插入图片描述

userbean的BeanDefinition应用PropertyPlaceholderConfigurer前:

在这里插入图片描述

userbean的BeanDefinition应用PropertyPlaceholderConfigurer后:

在这里插入图片描述

因为PropertyPlaceholderConfigurer不同的order导致应用的先后不同,order更小的PropertyPlaceholderConfigurer先应用了;后面的应用就无效了

在这里插入图片描述

所以最后是PropertyPlaceholderConfigurer order更小的那个。

userBean的name的set

回顾bean的生命周期:https://doctording.blog.csdn.net/article/details/145044487

在userBean的属性设置populateBean阶段,获取到bean的所有PropertyValue,逐一设置

在这里插入图片描述

最后反射设置完成:
在这里插入图片描述

总结

  1. 普通bean应用PropertyPlaceholderConfigurer的时候,如果有多个PropertyPlaceholderConfigurer,应该要有顺序,属性相同的取order小的即高优先级的
  2. 具体是通过PropertyPlaceholderConfigurer改变BeanDefintion, 后续bean生命周期的populateBean阶段完成属性设置

http://www.kler.cn/a/532912.html

相关文章:

  • 算法日记11:SC63(离散化)
  • 刷题记录 动态规划-7: 63. 不同路径 II
  • openRv1126 AI算法部署实战之——Tensorflow模型部署实战
  • Unity 2D实战小游戏开发跳跳鸟 - 计分逻辑开发
  • 机器学习中的关键概念:通过SKlearn的MNIST实验深入理解
  • MSP430 单独使用CCR1不触发的问题解决
  • Verilog基础(三):过程
  • INA226的初次使用
  • Java基础学习笔记-标识符、变量、常量、关键字
  • 【C++】Lambda表达式
  • Linux 文件和目录
  • 图像增广:用OpenCV实现的6个自动图像增强策略
  • 【数据分析】豆瓣电影Top250的数据分析与Web网页可视化(numpy+pandas+matplotlib+flask)
  • UE求职Demo开发日志#19 给物品找图标,实现装备增加属性,背包栏UI显示装备
  • ip属地是根据所在位置定位的吗
  • C#中的委托(Delegate)
  • Redis-BitMap实现签到功能
  • 2024美团春招硬件开发笔试真题及答案解析
  • JVM 四虚拟机栈
  • 暴力破解与验证码安全
  • LabVIEW涡轮诊断系统
  • 【深度学习】多层感知机的简洁实现
  • 渗透测试之文件包含漏洞 超详细的文件包含漏洞文章
  • 3、参数化测试
  • 【Redis实战】Chapter01-投票后端
  • 『 C++ 』中理解回调类型在 C++ 中的使用方式。