Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >spring-PropertyPlaceholderConfiger读取属性

spring-PropertyPlaceholderConfiger读取属性

作者头像
leobhao
发布于 2022-06-28 10:32:23
发布于 2022-06-28 10:32:23
67100
代码可运行
举报
文章被收录于专栏:涓流涓流
运行总次数:0
代码可运行

概述

spring在读取配置文件的时候,我们时常使用@Value注解来注入配置文件中的配置,在配置文件中也可以通过${}的方式来引用已经申明的配置,这是依靠Spring提供的PropertyPlaceholderConfigure来实现的。

PropertyPlaceholderConfigure调用流程

PropertyPlaceholderConfigure的父类PropertyResourceConfigurer是一个实现了BeanFactoryPostProcessors的类,所以它在spring的生命周期中会被调用。PropertyResourceConfigurer的实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    try {
        Properties mergedProps = mergeProperties();

        // Convert the merged properties, if necessary.
        convertProperties(mergedProps);

        // Let the subclass process the properties.
        processProperties(beanFactory, mergedProps);
    }
    catch (IOException ex) {
        throw new BeanInitializationException("Could not load properties", ex);
    }
}
  • mergeProperties主要是从硬盘中加载properties文件
  • convertProperties用来对PropertyValue做一些自定义对转换,默认是返回原值
  • processProperties是具体的properties的替换逻辑
PropertyPlaceholderConfigure-PropertyPlaceholderConfigure

PropertyPlaceholderConfigure实现替换properties逻辑如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
        throws BeansException {

    StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
    doProcessProperties(beanFactoryToProcess, valueResolver);
}

PlaceholderResolvingStringValueResolver封装了通过占位符从配置文件中获取对应配置的逻辑。大概的思路是遍历BeanDefinition进行占位符替换,在父类PlaceholderConfigurerSupportdoProcessProperties中实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
            StringValueResolver valueResolver) {

        BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);

        String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
        for (String curName : beanNames) {
            if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
                BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
                try {
                    visitor.visitBeanDefinition(bd);
                }
                catch (Exception ex) {
                    throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
                }
            }
        }

        // New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
        beanFactoryToProcess.resolveAliases(valueResolver);

        // New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
        beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
    }

visitBeanDefinition对文件中对占位符进行了替换,而@Value注解中占位符,则通过内嵌ValueResolver的方式,创建bean的时候进行替换

替换占位符对逻辑-BeanDefinitionVisitor

BeanDefinitionVisitor封装了操作BeanDefinition的逻辑,对占位符进行了替换:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void visitBeanDefinition(BeanDefinition beanDefinition) {
    visitParentName(beanDefinition);
    visitBeanClassName(beanDefinition);
    visitFactoryBeanName(beanDefinition);
    visitFactoryMethodName(beanDefinition);
    visitScope(beanDefinition);
    if (beanDefinition.hasPropertyValues()) {
        visitPropertyValues(beanDefinition.getPropertyValues());
    }
    if (beanDefinition.hasConstructorArgumentValues()) {
        ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
        visitIndexedArgumentValues(cas.getIndexedArgumentValues());
        visitGenericArgumentValues(cas.getGenericArgumentValues());
    }
}

重写PropertyPlaceholderConfigurer

在项目中,我们有时候需要从其他地方(并非项目中的properties文件)读取配置,替换我们在代码中定义的@Value注解标识的变量,比如我们把一些变量定义在了zk,这个时候我们就需要重写PropertyPlaceholderConfigurerprocessProperties

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class CustomPropertyPlaceholderConfigure extends PropertyPlaceholderConfigurer {


    private static final Logger logger = LoggerFactory.getLogger(CustomPropertyPlaceholderConfigure.class);

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
        // 设置为false,将占位符交给其他placeholder来解决
        this.setIgnoreUnresolvablePlaceholders(true);
        // 从此处读取zk,然后put进来
        ........
        super.processProperties(beanFactoryToProcess, props);
    }
}

注意这里this.setIgnoreUnresolvablePlaceholders(true);,这个标志如果为true的话,如果有无法解析的占位符就忽略,如果为false的话,就会抛出异常,默认为false。

这里我的理解是,每个 PropertyPlaceholderConfigure 都会去读自己定义的properties文件的位置,如果不设置ignore就会无法解析其他PropertyPlaceholderConfigure的properties,从而抛出异常

参考资料

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
详解PropertyPlaceholderConfigurer、PropertyOverrideConfigurer等对属性配置文件Properties的加载和使用【享学Spring】
本文主要从PropertiesLoaderSupport和PropertyResourceConfigurer出发,聊聊由它衍生出来的一些实用API。(和加载Properties有关) Spring的PropertyResourceConfigurer是个抽象类,继承自PropertiesLoaderSupport,并实现了接口BeanFactoryPostProcessor。
YourBatman
2019/09/03
3.6K0
详解PropertyPlaceholderConfigurer、PropertyOverrideConfigurer等对属性配置文件Properties的加载和使用【享学Spring】
BeanFactoryPostProcessor 和 BeanPostProcessor 有什么区别?
研究 Spring 源码的小伙伴可能会发现,Spring 源码中有很多名称特别相近的 Bean,我就不挨个举例了,今天我是想和小伙伴们聊一聊 Spring 中 BeanFactoryPostProcessor 和 BeanPostProcessor 两个处理器的区别。
江南一点雨
2023/09/09
6700
BeanFactoryPostProcessor 和 BeanPostProcessor 有什么区别?
Spring BeanFactoryPostProcessor 的作用时机详解
在前面的文章中,松哥已经和大家分享了 BeanPostProcessor 和 BeanFactoryPostProcessor 的基本用法以及差别,但是没有去分析其原理,今天我们就来聊一聊这两个后置处理器的工作原理。
江南一点雨
2023/09/20
5860
Spring BeanFactoryPostProcessor 的作用时机详解
老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?【享学Spring】
写这篇文章的原动力是由于昨晚深夜一个小伙伴咨询我的一个问题(这位小伙伴这么晚了还在折腾,也是给个大大的赞),涉及到了如题方面的知识。 当然促使我书写本文最重要原因的是:这种从传统Spring项目向SpringBoot迁移进阶的case,我个人认为在现阶段的环境下还是有较大概率出现的,因此推荐收藏本文,对你后续或许有所帮助~
YourBatman
2019/09/03
1.9K0
老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?【享学Spring】
【死磕 Spring】----- IOC 之深入分析 PropertyOverrideConfigurer
在文章 【死磕 Spring】----- IOC 之 深入分析 BeanFactoryPostProcessor 中提到,BeanFactoryPostProcessor 作用与 bean 完成加载之后与 bean 实例化之前,是 Spring 提供的一种强大的扩展机制,他有两个重要的子类,一个是 PropertyPlaceholderConfigurer,另一个是 PropertyOverrideConfigurer ,其中 PropertyPlaceholderConfigurer 允许我们通过配置 Properties 的方式来取代 bean 中定义的占位符,而 PropertyOverrideConfigurer 呢?正是我们这篇博客介绍的。
用户1655470
2019/03/06
9310
【死磕 Spring】----- IOC 之深入分析 PropertyOverrideConfigurer
Spring中Bean的生命周期了解一下,面试不怕被问
上一篇我们介绍了Spring IOC容器的启动过程以及bean的实例化过程,这一篇我们接着来学习另外一个知识点,就是Bean的生命周期,我们知道直接通过(new XX())来创建的实例,当这个实例没有被引用时就会被垃圾回收机制回收,但是通过IOC容器实例化的Bean的生命周期又是如何呢?IOC容器负责管理容器中所有的bean的生命周期,而在bean生命周期的不同阶段,Spring提供了不同的扩展点来改变bean的命运。当然容器只能帮助我们管理单例模式bean的完整生命周期,对于property的bean,Spring在创建好交给使用者之后则不会在管理后续的生命周期。
码农飞哥
2021/08/18
1.1K0
PropertyPlaceholderConfigurer 用法
PropertyPlaceholderConfigurer 用法一、PropertyPlaceholderConfigurer 的继承体系二、PropertyPlaceholderConfigurer 的基本概念三、PropertyPlaceholderConfigurer 的基本使用PropertyPlaceholderConfigurer 引入外部属性文件PropertyPlaceholderConfigurer 引入多个属性文件PropertyPlaceholderConfigurer 的替代方案四、自定义PropertyPlaceholderConfigurer
cxuan
2019/06/04
5.2K0
PropertyPlaceholderConfigurer 用法
Spring IoC 容器扩展
托管给Spring IoC 容器的Bean虽然不知道容器的存在,但是容器也提供了完整的扩展点,让使用者动态干预bean的定义和实例化,以及生命周期相关的钩子。
李鸿坤
2020/07/18
5790
京东技术解密之配置中心DUCC
支持多环境(或称分组),分组可以合并 内置强大的基于插件的数据绑定框架,支持多种类型转换; 支持Log4j、Log4j2、Logback的动态修改日记级别功能。 支持Spring原生注解、支持自定义注解,客户端代码入侵性低 支持客户端多配置源,支持自定义配置,如ZK、Consol扩展 支持配置预案切换
公众号_松华说
2019/07/16
10.6K1
京东技术解密之配置中心DUCC
Spring IoC是如何使用BeanWrapper和Java内省结合起来给Bean属性赋值的【享学Spring】
书写此篇博文的缘由是出自一道面试题:面试题目大概如标题所述。 我个人认为这道面试题问得是非常有水平的,因为它涉及到的知识点既有深度,又有广度,可谓一举两得~~~因此在这里分享给大家。
YourBatman
2019/09/03
1.1K0
Spring IoC是如何使用BeanWrapper和Java内省结合起来给Bean属性赋值的【享学Spring】
《Spring 手撸专栏》第 15 章:万人之敌,通过注解给属性注入配置和Bean对象
你听过扰动函数吗?你写过斐波那契(Fibonacci)散列吗?你实现过梅森旋转算法吗?怎么 没听过这些写不了代码吗!不会的,即使没听过你一样可以写的了代码,比如你实现的数据库路由数据总是落在1库1表它不散列分布、你实现的抽奖系统总是把运营配置的最大红包发出去提高了运营成本、你开发的秒杀系统总是在开始后的1秒就挂了货品根本给不出去。
小傅哥
2021/08/20
6170
《Spring 手撸专栏》第 15 章:万人之敌,通过注解给属性注入配置和Bean对象
面试官:展开说说,Spring中Bean对象是如何通过注解注入的?
你听过扰动函数吗?你写过斐波那契(Fibonacci)散列吗?你实现过梅森旋转算法吗?怎么 没听过这些写不了代码吗!不会的,即使没听过你一样可以写的了代码,比如你实现的数据库路由数据总是落在1库1表它不散列分布、你实现的抽奖系统总是把运营配置的最大红包发出去提高了运营成本、你开发的秒杀系统总是在开始后的1秒就挂了货品根本给不出去。
小傅哥
2021/08/04
8550
面试官:展开说说,Spring中Bean对象是如何通过注解注入的?
Springboot 随笔(2)-- Properties 配置一坑
SpringBoot的迁移过程中碰到的奇葩坑 什么坑? 原Spring项目迁移成SpringBoot项目,早前使用 PropertyPlaceholderConfigurer  配置properties引入,在使用properties中的配置项时报错,如 ${user.name} 配置项找不到,有时又可以但 application.properties 中配置项找不到。 要找到问题关键先要知道Spring处理配置项注入是怎么实现的。 Spring 配置项注入 1. Spring注入方式 XML注入 <
alexqdjay
2018/05/11
1.3K0
深入剖析Spring(二)——IoC容器的实现
Spring的两种IoC容器 BeanFactory 基础类型的IoC容器; 采用延迟初始化策略(容器初始化完成后并不会创建bean的对象,只有当收到初始化请求时才进行初始化); 由于延迟初始化
大闲人柴毛毛
2018/03/09
8930
深入剖析Spring(二)——IoC容器的实现
Spring源码阅读之一
众所周知,阅读spring源码最开始的就是去了解spring bean的生命周期:bean的生命周期是怎么样的呢,见图知意:
@派大星
2023/07/15
3550
Spring源码阅读之一
spring系列之自定义扩展PropertyPlaceHolderConfigurer
一、PropertyPlaceHolderConfigurer介绍 主要用于将一些配置信息移出xml文件,移到至properties文件 二、拓展使用 1、将porperties内容设置成java全局可读 思路:spring启动的时候会将properties加载至其指定缓存机制,可利用其加载机制,在读取properties时,保存一份至变量,对外提供访问接口。 1.1 创建PropertyPlaceHolderConfigurer的子类,代码如下CustomPropertyPlaceConfigurer
lyb-geek
2018/03/27
3.6K0
配置文件properties读取使用的好方法
  首先在spring配置文件applicationContext.xml中配置、
老梁
2019/09/10
6940
spring:property-override
允许我们使用属性文件(.properties)的形式对bean的属性进行替换。下面是一个简单的demo:
MickyInvQ
2021/10/19
5170
【死磕 Spring】—– IOC 之 深入分析 BeanFactoryPostProcessor
在博客 【死磕 Spring】----- IOC 之 深入分析 BeanPostProcessor 深入介绍了 BeanPostProcessor 的实现机制。在这篇文章中提到 BeanPostProcessor 是 Spring 提供一种扩展机制,该机制允许我们在 Bean 实例化之后初始化之际对 Bean 进行增强处理(前、后置处理)。同样在 Spring 容器启动阶段,Spring 也提供了一种容器扩展机制:BeanFactoryPostProcessor,该机制作用于容器启动阶段,允许我们在容器实例化 Bean 之前对注册到该容器的 BeanDefinition 做出修改。
用户1655470
2019/01/02
1.1K0
Spring复杂的BeanFactory继承体系该如何理解? ----上
Spring提供了两种容器类型:BeanFactory和ApplicationContext。
大忽悠爱学习
2022/05/10
1.9K0
Spring复杂的BeanFactory继承体系该如何理解? ----上
推荐阅读
相关推荐
详解PropertyPlaceholderConfigurer、PropertyOverrideConfigurer等对属性配置文件Properties的加载和使用【享学Spring】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验