.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.markdown-body pre, .markdown-body pre>code.hljs { color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.hljs-comment, .hljs-quote { color: rgba(153, 153, 136, 1); font-style: italic }
.hljs-keyword, .hljs-selector-tag, .hljs-subst { color: rgba(51, 51, 51, 1); font-weight: 700 }
.hljs-literal, .hljs-number, .hljs-tag .hljs-attr, .hljs-template-variable, .hljs-variable { color: rgba(0, 128, 128, 1) }
.hljs-doctag, .hljs-string { color: rgba(221, 17, 68, 1) }
.hljs-section, .hljs-selector-id, .hljs-title { color: rgba(153, 0, 0, 1); font-weight: 700 }
.hljs-subst { font-weight: 400 }
.hljs-class .hljs-title, .hljs-type { color: rgba(68, 85, 136, 1); font-weight: 700 }
.hljs-attribute, .hljs-name, .hljs-tag { color: rgba(0, 0, 128, 1); font-weight: 400 }
.hljs-link, .hljs-regexp { color: rgba(0, 153, 38, 1) }
.hljs-bullet, .hljs-symbol { color: rgba(153, 0, 115, 1) }
.hljs-built_in, .hljs-builtin-name { color: rgba(0, 134, 179, 1) }
.hljs-meta { color: rgba(153, 153, 153, 1); font-weight: 700 }
.hljs-deletion { background: rgba(255, 221, 221, 1) }
.hljs-addition { background: rgba(221, 255, 221, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }

简介

Spring启动部分流程:

  • Spring IOC读取Bean的相关属性,保存到beanDefinition对象中。
  • 加载完所有beanDefinition之后,调用BeanFactoryPostProcessor接口扩展点。
  • 根据beanDefinition创建bean对象。

如果想获取beanDefinition信息或者修改BeanDefinition对象中的属性, 可以实现BeanFactoryPostProcessor进行修改。

public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

用途示例

Spring应用读取配置

抽象类:PropertyResourceConfigurer, 主要做的就是读取properties文件,做一些必要的转换,并将这些properties写到bean Definition中。

public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport
implements BeanFactoryPostProcessor, PriorityOrdered { private int order = Ordered.LOWEST_PRECEDENCE; // default: same as non-Ordered // 略:serOrder / getOrder @Override
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);
}
}
}

它有两个实现类:

  • PropertyOverrideConfigurer:比如数据库配置为"dataSource.driverClassName=com.mysql.jdbc.Driver",这个类负责将这个value从配置文件中(比如叫datasource.properties)读取配置写到相应的beanDefinition中。

  • PropertyPlaceholderConfigurer ,这个类可以将代码中定义的"${...}"替换为配置文件中的实际的值。

在Spring启动时打印相关信息, 比如bean的个数,统计指定特性的bean信息,修改beanDefinition, 甚至注册BeanDefinition。

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory; int count = defaultListableBeanFactory.getBeanDefinitionCount();
System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory共有" + count + "个bean"); String[] beanDefinitionNames = defaultListableBeanFactory.getBeanDefinitionNames(); //修改属性
for (String beanName : beanDefinitionNames) {
if ("person".equals(beanName)) {
//获取PersonDefinition对象
BeanDefinition beanDefinition = defaultListableBeanFactory.getBeanDefinition(beanName);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
System.out.println(propertyValues.toString());
//修改定义中的name属性值
propertyValues.addPropertyValue("name", "赵四");
System.out.println("[MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了");
}
} //手动注册User的BeanDefiniton
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("id", 123);
beanDefinitionBuilder.addPropertyValue("name", "修改definition");
defaultListableBeanFactory.removeBeanDefinition("user");
defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
}
}

更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…

Spring扩展接口-BeanFactoryPostProcessor的更多相关文章

  1. spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.BeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessor简述与demo示例 ...

  2. Spring8:一些常用的Spring Bean扩展接口

    前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...

  3. 0001 - Spring 框架和 Tomcat 容器扩展接口揭秘

    前言 在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存.Bean 的创建. ...

  4. 深入理解Spring系列之八:常用的扩展接口

    转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...

  5. spring初始化源码浅析之关键类和扩展接口

    目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...

  6. Spring拓展接口之BeanFactoryPostProcessor,占位符与敏感信息解密原理

    前言 开心一刻 一只被二哈带偏了的柴犬,我只想弄死隔壁的二哈 what:是什么 BeanFactoryPostProcessor接口很简单,只包含一个方法 /** * 通过BeanFactoryPos ...

  7. spring扩展点整理

    本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...

  8. spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...

  9. spring源码分析系列 (2) spring拓展接口BeanPostProcessor

    Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...

  10. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

随机推荐

  1. BUGKU_PWN_OVERFLOW2_WP

    WP_OVERFLOW2 拿到程序,首先放到我们的kali里面看看是多少位的程序,然后在看看有没有什么安全属性 64位程序,并且开启了RELRO,NX 也就是说,这道题我们需要使用ROP绕过 使用id ...

  2. python 函数与方法的区别

    函数与方法的区别 并不是类中的调用都叫方法 1.函数要手动传self,方法不用传self. 2.如果是一个函数,用类名去调用,如果是一个方法,用对象去调用. class Foo(object): de ...

  3. 项目管理知识体系指南(PMBOK 指南)

    项目管理知识体系指南(PMBOK 指南) 第6版--笔记项目管理十大知识领域,五大管理过程组,49个过程.如下表格:项目:项目的定义 : (Project Management Institute)项 ...

  4. 通俗易懂分布式事务之2PC、3PC、Seata AT模式、Seata TCC模式

    通俗易懂分布式事务之2PC.3PC.AT.TCC 单机服务事务提交回滚操作是需要拿到Connection对象,调用提交commit方法或者rollback方法回滚的,例如下面操作 Connection ...

  5. 虚拟机为什么ping不通主机

    在虚拟机里各种操作都正常.就是ping不通主机.为什么? NAT模式下(网络地址转换模式),虚拟机后网络适配器就会出现VMnet8网卡: 把VMnet8的ip4设定成你主机同段IP.这个VMnet8地 ...

  6. Mybatis常用配置参数

    Mybatis-plus官方配置详细文档:  https://mp.baomidou.com/config/常用配置参数如下: mybatis-plus: # mapper配置文件路径 mapper- ...

  7. 在IM即时通讯系统中接入DeepSeek等AI大模型

    随着DeepSeek的热潮,越来越多的企业也开始部署并训练自己的AI大模型,这样能使企业以前沉淀的专业知识和经验能更高效地被利用起来.有客户反馈了这样的需求场景:客户私有部署了自己的AI大模型以及私有 ...

  8. Asp.net mvc基础(七)cshtml页面中自动using

    场景如下: 在cshtml页面中,如果要在页面中进行初始化一个类的时候,需要添加这个类的命名空间才可以. 对于这种情况,我们可以通过配置Web.config达到在cshtm页面的使用类的时候不需要进行 ...

  9. Java编程之面向对象

    一.面向对象 1.定义 (1)类:描述的是具有共性的一类事物 (2)对象:一个个具备了类的特点和功能的个体 (3)面向对象:要完成某件事,首先要先有对象,然后直接调用这个对象的响应功能 2.成员变量: ...

  10. [笔记]image对象如何添加class

    1.image对象可以添class,但不能以属性.class的方法添加,而因该把他当成一个节点 2.JS添加和删除class名 添加:节点.classList.add("类名"): ...