首页 > 其他分享 >Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理

时间:2023-11-10 12:31:49浏览次数:33  
标签:调用 Spring 代码 56 PropertySourcePlaceholderConfigurer 如下 spring 方法 属性


PropertySourcePlaceholderConfigurer的用途:通过配置文件(比如.properties文件)给bean设置属性,替代属性占位符
示例:

属性配置文件

spring.datasource.url=jdbc:mysql://xxx.xxx.xxx.xxx/test
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring配置文件:

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



    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="locations" value="classpath:cn/edu/tju/jdbc.properties"/>
    </bean>

    <bean id="dataSource"
          class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${spring.datasource.driver-class-name}"/>
        <property name="url" value="${spring.datasource.url}"/>
        <property name="username" value="${spring.datasource.username}"/>
        <property name="password" value="${spring.datasource.password}"/>
    </bean>


</beans>

因为在spring配置文件定义了类型为PropertySourcesPlaceholderConfigure的BeanFactoryPostProcessor,所以在容器创建dataSource这个bean时,它会对bean定义进行处理,将属性中的占位符替换为实际值。

工作原理:

当实例化PropertySourcesPlaceholderConfigurer时,通过属性注入,把bean配置时指定的属性文件名字对应的Resource保存到其父类的locations成员变量

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml


因为PropertySourcesPlaceholderConfigurer是BeanFactoryPostProcessor,所以其postProcessBeanFactory方法会被调用,这个方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_后端_02


Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_mvc_03


其中调用了processProperties方法,该方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_mvc_04


从上图看出,它调用了父类的doProcessProperties方法:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_spring_05


其中调用了BeanDefinitionVistor的局部变量的visitBeanDefinition方法,这个方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_06


可以看到它首先判断BeanDefinition中是否存在属性值,如果存在,则调用visitPropertyValues方法来进行处理,这个方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_spring_07


其中调用的resolveValue方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_后端_08


Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_09


其中调用的resolveStringValue方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_10


可以看到它调用了成员变量valueResolver来对属性进行处理,而此处的valueResolver是创建BeanDefinitionReader时通过lambda表达式传进来的,如下图

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_spring_11


因为this.ignoreUnresolvablePlaceholders为false,所以会执行propertyResolver.resolveRequiredPlaceholders(strVal),这个方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_12


它调用的doResolvePlaceholders代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_java_13


它调用的辅助类的replacePlaceholders方法,代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_spring_14

它调用的parseStringValue代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_后端_15


Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_mvc_16


Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_17


其中,`

String propVal = placeholderResolver.resolvePlaceholder(placeholder);

这句完成了真正的属性解析,这里的placeholderResolver是通过lambda表达式传进来的,如下图:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_mvc_18


此处的getPropertyAsRawString代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_spring_19


它调用的getProperty方法代码如下:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_mvc_20


从上图可以看出,这个方法中会遍历拿到的PropertySource,根据传入的key拿到我们在属性配置文件中配置的值,然后返回,到此,从属性文件中读取属性信息的过程结束。

流程一步一步往回返,回到BeanDefinitionVisitor类:

Spring复习:(56)PropertySourcePlaceholderConfigurer的工作原理_xml_21


最后把从属性文件中获取到的值设置到pvs中,因为pvs是BeanDefinition的引用,因此,设置完成之后,beanDefinition也就被改变了


标签:调用,Spring,代码,56,PropertySourcePlaceholderConfigurer,如下,spring,方法,属性
From: https://blog.51cto.com/amadeusliu/8295887

相关文章

  • 【Spring】一次性打包学透 Spring | 阿Q送书第五期
    文章目录如何竭尽可能确保大家学透Spring1.内容全面且细致2.主题实用且本土化3.案例系统且完善4.知识有趣且深刻关于作者丁雪丰业内专家推图书热卖留言提前获赠书不知从何时开始,Spring这个词开始频繁地出现在Java服务端开发者的日常工作中,很多Java开发者从工作的第一天......
  • SpringBoot部署的jar包瘦身
    pom文件打包插件更换参考连接:https://www.jb51.net/program/293676eog.htm参考连接:https://blog.csdn.net/meng_9543/article/details/121329834<build><finalName>xxx-xxx</finalName><plugins><plugin>......
  • Spring BeanUtils.copyProperties简化写法
    代码importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importorg.springframework.beans.BeanUtils;importorg.springframework.beans.BeansException;importorg.springframework.util.StopWatch;publicclassBeanUtils2{......
  • springboot学习日记(一)
    今天连下数据库,不小心打成netstartmysql了,好糗。。以后等时机到了笔记也该换成markdown写了,好久没写md后面得复习下。然后idea这边连数据库很简单不用写专门的程序,右侧栏database直接可以点开具体到连接某个数据库。记录一下注解的原理和作用:以前,『XML』是各大框架的青睐者,它......
  • Springboot报错,java.lang.IllegalArgumentException: argument type mismatch
    1、报错信息java.lang.IllegalArgumentException:argumenttypemismatch atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod) atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) atsun.reflect.DelegatingMethodAccessorI......
  • 「Java开发指南」如何用MyEclipse搭建Spring MVC应用程序?(二)
    本教程将指导开发者如何生成一个可运行的SpringMVC客户应用程序,该应用程序实现域模型的CRUD应用程序模式。在本教程中,您将学习如何:从数据库表的Scaffold到现有项目部署搭建的应用程序在上文中,我们介绍了如何创建一个Web项目和来自数据库表的Scaffold等,本文将继续介绍如何部......
  • 如何让spring一直启动不关掉
    Spring是J2EE应用程序框架,深受java程序员的欢迎,大量的项目都会引入Spring框架。如果是web项目,启动Spring之后,web容器会维持进程持续运行,Spring也就可以一直出于启动状态,但如果是普通的java应用,在启动Spring之后,随着java进程的停止,spring也会停止。那么如何让spring一直启动持续服......
  • SpringCloud 集成 Sentinel 和使用小结
    Sentinel是阿里的一款微服务请求监控组件,能够通过配置实现流量控制,降级熔断,热点参数限流,授权规则限流,使用非常方便。官方默认只提供了流量控制配置规则持久化代码实现,这也是我们最常用的,上篇博客已经实现并进行了部署。本篇博客基于上篇博客搭建好的Sentinel和Nacos环境,介绍......
  • springboot社区团购管理系统的设计与实现-计算机毕业设计源码+LW文档
    abo开发说明开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9浏览器:谷歌浏览器部分数据库:----Tablestructurefortableaddress--DROPTABLEIFEXISTSaddr......
  • springboot科研管理系统-计算机毕业设计源码+LW文档
    摘 要随着计算机技术发展,计算机系统的应用已延伸到社会的各个领域,大量基于网络的广泛应用给生活带来了十分的便利。所以把科研管理与现在网络相结合,利用计算机搭建科研管理系统,实现科研的信息化。则对于进一步提高科研管理发展,丰富科研管理经验能起到不少的促进作用。系统阐述......