Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

作者:融极 时间:2023-11-24 23:24:21 

BeanDefinitionRegistryPostProcessor概述

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

可以看到BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。

注释中说执行时机是所有合法的bean定义已经加载,但是还没实例化。

看起来和BeanFactoryPostProcessor执行时机差不多,但是BeanFactoryPostProcessor的注释是所有bean定义被加载,而BeanDefinitionRegistryPostProcessor是所有合法的bean定义。

接着看注释:

This allows for adding further bean definitions before the next post-processing phase kicks in.

意思是BeanDefinitionRegistryPostProcessor允许添加将来的bean定义在下一个后置处理器阶段开始之前。简单说就是还可以往容器中增加新的bean的定义。

因此,大概率BeanDefinitionRegistryPostProcessor的执行顺序在BeanFactoryPostProcessor之前。

案例实践

首先,编写一个类,例如MyBeanDefinitionRegistryPostProcessor,它应要实现BeanDefinitionRegistryPostProcessor这个接口。

package com.meimeixia.ext;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

import com.meimeixia.bean.Blue;

// 记住,我们这个组件写完之后,一定别忘了给它加在容器中
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:" + beanFactory.getBeanDefinitionCount());
}

/**
* 这个BeanDefinitionRegistry就是Bean定义信息的保存中心,这个注册中心里面存储了所有的bean定义信息,
* 以后,BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息来创建bean实例的。
*
* bean定义信息包括有哪些呢?有这些,这个bean是单例的还是多例的、bean的类型是什么以及bean的id是什么。
* 也就是说,这些信息都是存在BeanDefinitionRegistry里面的。
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:" + registry.getBeanDefinitionCount());
// 除了查看bean的数量之外,我们还可以给容器里面注册一些bean,我们以前也简单地用过
/*
* 第一个参数:我们将要给容器中注册的bean的名字
* 第二个参数:BeanDefinition对象
*/
// RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); // 现在我准备给容器中添加一个Blue对象
// 咱们也可以用另外一种办法,即使用BeanDefinitionBuilder这个构建器生成一个BeanDefinition对象,很显然,这两种方法的效果都是一样的
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}

测试结果

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

可以看到,BeanDefinitionRegistryPostProcessor里面的两个方法,postProcessBeanDefinitionRegistry在postProcessBeanFactory之前执行。

BeanDefinitionRegistryPostProcessor比BeanFactoryPostProcessor先执行。

源码分析

自己在测试示例中方法打断点,然后查看调用栈即可,下面是一些主要的代码片段。

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

继续向下看,可以看到会取出所有实现了BeanDefinitionRegistryPostProcessor接口的类,即从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。

然后,优先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor组件。

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

点进去这个方法里面一看究竟,原来是先调用完BeanDefinitionRegistryPostProcessor组件里面的postProcessBeanDefinitionRegistry方法,然后再来调用它里面的postProcessBeanFactory方法。

我们再来仔细看一下PostProcessorRegistrationDelegate类中的invokeBeanFactoryPostProcessors方法,只不过这时是从程序停留的地方(即第122行代码处)往下看,如下图所示。

Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

小结

BeanDefinitionRegistryPostProcessor的执行流程。

1. 创建IOC容器。

2. 调用refresh方法。

3. 从IOC容器中获取所有的BeanDefinitionRegistryPostProcessor组件,并依次触发它们的postProcessBeanDefinitionRegistry方法,之后触发它的postProcessBeanFactory方法。

4. 从IOC容器中获取到所有的BeanFactoryPostProcessor组件,并依次触发它们的postProcessBeanFactory方法。

来源:https://blog.csdn.net/tianzhonghaoqing/article/details/126918816

标签:Spring,注解驱动,BeanDefinitionRegistryPostProcessor
0
投稿

猜你喜欢

  • android中实现指针滑动的动态效果方法

    2023-10-07 15:54:44
  • 基于SpringCloudGateway实现微服务网关的方式

    2021-12-02 04:33:04
  • SpringBoot全局Controller返回值格式统一

    2022-09-12 14:07:52
  • C#正则表达式大全

    2023-12-04 13:06:37
  • java子类调用父类的方法中包含子类重写的实例方法

    2023-12-22 21:14:50
  • Java中比较运算符compareTo()、equals()与==的区别及应用总结

    2023-11-28 20:08:28
  • Springboot WebFlux集成Spring Security实现JWT认证的示例

    2021-06-02 03:24:50
  • Java编程中的一些常见问题汇总

    2022-01-08 18:05:46
  • Java多态性抽象类与接口细致详解

    2022-08-22 00:06:11
  • C# 操作符之二 算数操作符

    2023-06-19 20:21:13
  • 基于Java8 函数式接口理解及测试

    2021-06-19 21:54:35
  • java打印菱形及直角和等腰三角形的方法

    2023-01-08 20:46:55
  • Android实现界面左右滑动切换功能

    2022-08-30 02:00:58
  • AndroidManifest.xml <uses-feature>和<uses-permisstion>分析及比较

    2023-11-05 12:17:12
  • Android控件之CheckBox、RadioButton用法实例分析

    2021-06-01 06:31:26
  • winform实现可拖动的自定义Label控件

    2022-12-14 09:11:36
  • SpringBoot封装JDBC的实现步骤

    2022-09-13 04:04:31
  • Android基于Intent实现Activity之间数据传递的方法

    2022-08-01 16:34:04
  • java&javascript自定义加密数据传输代码示例

    2021-11-29 02:09:33
  • Android Bitmap详解及Bitmap的内存优化

    2022-06-27 13:44:55
  • asp之家 软件编程 m.aspxhome.com