Spring扩展接口(2):BeanDefinitionRegistryPostProcessor
在此系列文章中,我总结了Spring几乎所有的扩展接口,以及各个扩展点的使用场景。并整理出一个bean在spring中从被加载到最终初始化的所有可扩展点的顺序调用图。这样,我们也可以看到bean是如何一步步加载到spring容器中的。

BeanDefinitionRegistryPostProcessor
1、概述
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
BeanDefinitionRegistryPostProcessor为容器级后置处理器。容器级的后置处理器会在Spring容器初始化后、刷新前执行一次。还有一类为Bean级后置处理器,在每一个Bean实例化前后都会执行。
通常,BeanDefinitionRegistryPostProcessor用于在bean解析后实例化之前通过BeanDefinitionRegistry对BeanDefintion进行增删改查。
常见如mybatis的Mapper接口注入就是实现的此接口。
2、简单案例
下面是一个示例,展示了如何实现动态的给spring容器添加一个Bean:
public class User {
String name;
String password;
}
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
public class DynamicBeanRegistration implements BeanDefinitionRegistryPostProcessor, Ordered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanRegistry) throws BeansException {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(User.class);
MutablePropertyValues propertyValues = new MutablePropertyValues();
PropertyValue propertyValue1 = new PropertyValue("name", "张三");
PropertyValue propertyValue2 = new PropertyValue("password", "123456");
propertyValues.addPropertyValue(propertyValue1);
propertyValues.addPropertyValue(propertyValue2);
beanDefinition.setPropertyValues(propertyValues);
beanRegistry.registerBeanDefinition("user", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
System.out.println(beanDefinition.getBeanClassName());
User user = beanFactory.getBean(User.class);
System.out.println(user.getName());
System.out.println(user.getPassword());
}
@Override
public int getOrder() {
return 0;
}
}
输出:
com.sandy.springex.beanfefinitionregistrypostprocessor.User
张三
123456
- 首先定义了一个名为"User"的Java类,包含了两个属性:name和password。
- 然后定义了一个名为"DynamicBeanRegistration"的组件(通过@Component注解),实现了BeanDefinitionRegistryPostProcessor接口和Ordered接口。
- 在postProcessBeanDefinitionRegistry方法中,创建了一个RootBeanDefinition对象,并设置其beanClass为User类。接着创建了一个MutablePropertyValues对象,并通过PropertyValue对象设置了name和password属性的值。最后,将propertyValues设置到beanDefinition中,并使用beanRegistry注册了一个名为"user"的BeanDefinition。
- 在postProcessBeanFactory方法中,通过beanFactory获取了名为"user"的BeanDefinition,并输出了其beanClassName。然后使用beanFactory获取了一个User对象,并输出了其name和password属性的值。
该代码通过实现BeanDefinitionRegistryPostProcessor接口,在Spring容器启动时动态注册了一个名为"user"的Bean,并设置了其name和password属性的值。在后续的BeanFactory初始化过程中,可以通过beanFactory获取到该动态注册的Bean,并访问其属性值。
当容器中有多个BeanDefinitionRegistryPostProcessor的时候,可以通过实现Ordered接口来指定顺序:
@Override
public int getOrder() {
return 0; //值越小,优先级越高
}
3、源码分析
- 在DynamicBeanRegistration打上断点,启动SpringApplication,可以看到左下角的调用链路。

- 红框中5步都是在springboot中进行,最后super.refresh()是调用大家熟悉的spring的AbstractApplicationContext的refresh方法。

- 继续向下看


- 接下来进入核心的invokeBeanFactoryPostProcessors方法,大概逻辑是先取出所有实现了BeanDefinitionRegistryPostProcessor接口的类,然后优先调用实现了PriorityOrdered接口的组件,再调用实现了Ordered接口的组件。

- 最后,遍历调用BeanDefinitionRegistryPostProcessor组件postProcessBeanDefinitionRegistry方法

Spring扩展接口(2):BeanDefinitionRegistryPostProcessor的更多相关文章
- 0001 - Spring 框架和 Tomcat 容器扩展接口揭秘
前言 在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存.Bean 的创建. ...
- Spring8:一些常用的Spring Bean扩展接口
前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...
- 深入理解Spring系列之八:常用的扩展接口
转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...
- spring初始化源码浅析之关键类和扩展接口
目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...
- spring扩展点整理
本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...
- spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入
<spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...
- PHP安装memcache扩展接口步骤
1.将php_memcache.dll文件保存到php的应用程序扩展ext目录中 2.在php.ini配置文件添加扩展的位置,加入一行extension=php_memcache.dll 3.重新启动 ...
- hibernate核心接口,和扩展接口。回顾笔记,以前没记,现在补上,纯手工敲的。
hibernate核心接口: 所有的hibernate应用都会访问hibernate的5个核心接口 1,Configuration接口 Configuration用于配置并且根启动Hibernate. ...
- Java开发笔记(五十九)Java8之后的扩展接口
前面介绍了接口的基本用法,有心的朋友可能注意到这么一句话“在Java8以前,接口内部的所有方法都必须是抽象方法”,如此说来,在Java8之后,接口的内部方法也可能不是抽象方法了吗?之所以Java8对接 ...
随机推荐
- Prompt 手册——gpt-best-practices
本文链接:https://www.cnblogs.com/wanger-sjtu/p/17470388.html 本文是 OpenAI gpt-best-practices 对如何使用GPT的Prom ...
- LLE算法的应用场景和案例:详解LLE算法在实际问题中的效果和表现
目录 引言 随着深度学习技术的不断发展,神经网络模型在人工智能领域的应用越来越广泛.其中,LLE(Largely Element-wise Linear) 神经网络是一种常用的神经网络模型,其基本思想 ...
- FPGA加速技术:在数据中心和云计算中的应用
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成与测试 4. 应用示例与代码实现讲解 4.1. 应用场景介绍 4. ...
- SpringBoot对接阿里云OSS上传文件以及回调(有坑)
前言 今天在对接阿里云OSS对象存储, 把这过程记录下来 链接 阿里云的内容很多,文档是真的难找又难懂 本文主要是用的PostObject API 加上 Callback参数 PostObject - ...
- 脱发秘籍:前端Chrome调试技巧汇总
Chrome浏览器调试工具的核心功能: 注:本文测试.截图均为Edge浏览器(内核是Chromium),浏览器内核可了解<有哪些浏览器/内核?> 00.基础操作汇总 操作类型 快捷键/说明 ...
- Java IO流 - 字节流的使用详细介绍
IO流的基本介绍: IO流的概述: i 表示intput,是数据从硬盘文件读入到内存的过程,称之输入,负责读. o 表示output,是内存程序的数据从内存到写出到硬盘文件的过程,称之输出,负责写. ...
- jquery解决跨域问题
在Ajax请求的url不是本地或者同一个服务器下面的URI,最后虽然请求显示为200,但是不会返回任何数据,事实上简单来说请求同一个域名下的url或者说用不带http的绝对路径和相对路径请求是没有任何 ...
- pandas对某列数据进行求和
求和的方式很简单,如下所示: number_of_declarations = data[4].sum()//中括号中为要求和的列
- asp.net core之Options
本文将介绍 ASP.NET Core 中的 Options 概念和使用方法.Options 是一种配置管理机制,可以将应用程序的配置信息从代码中分离出来,提高代码的可维护性和可测试性.我们将详细介绍如 ...
- MySQL5.5+配置主从同步并结合ThinkPHP5设置分布式数据库
前言: 本文章是在同处局域网内的两台windows电脑,且MySQL是5.5以上版本下进行的一主多从同步配置,并且使用的是集成环境工具PHPStudy为例.最后就是ThinkPHP5的分布式的连接,读 ...