spring中的BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,BeanFactoryPostProcessor的作用是在bean

的定义信息已经加载但还没有初始化的时候执行方法postProcessBeanFactory()方法,而BeanDefinitionRegistryPostProcessor是在

BeanFactoryPostProcessor的前面执行。

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

    /**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }

自定义一个实现了BeanDefinitionRegistryPostProcessor接口的MyBeanDefinitionRegistryPostProcessor 实现类,它会重写

BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法和BeanFactoryPostProcessor的postProcessBeanFactory()方法

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
     //BeanDefinitionRegistry可以给容器注册bean 
System.out.println("MyBeanDefinitionRegistryPostProcessor...添加了foo之前的bean数="+registry.getBeanDefinitionCount());
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Foo.class);
registry.registerBeanDefinition("helloFoo",rootBeanDefinition);
} @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanFactory...的bean数="+beanDefinitionCount);
}
}

配置类:

@Configuration
@Import({MyBeanDefinitionRegistryPostProcessor.class})
public class ExtConfig { @Bean
public Foo foo(){
return new Foo();
}
}

foo类:

public class Foo {

    public Foo(){
System.out.println("bean的创建");
} @PostConstruct
public void init(){
System.out.println("bean的初始化");
} @PreDestroy
public void destroy(){
System.out.println("bean的销毁");
}
}

测试结果:

MyBeanDefinitionRegistryPostProcessor...添加了foo之前的bean数9
MyBeanDefinitionRegistryPostProcessor...postProcessBeanFactory...的bean数+10
bean的创建
bean的初始化
bean的创建
bean的初始化

debug:refresh()--》invokeBeanFactoryPostProcessors(),这里和注册bean和beanFactory类似,按照优先级的的来进行。

    // Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
} // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
invokeBeanDefinitionRegistryPostProcessors()方法:
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}

最后去执行invokeBeanFactoryPostProcessors()方法;

/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

它获取到所有的BeanFactoryPostProcessor 后,遍历执行每一个具体的方法:在这里会去调用

MyBeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法:

spring中的BeanDefinitionRegistryPostProcessor的更多相关文章

  1. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  2. Spring Boot 使用Java代码创建Bean并注册到Spring中

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/catoop/article/details/50558333 声明同一个类下的多个实例: packa ...

  3. 0000 - Spring 中常用注解原理剖析

    1.概述 Spring 框架核心组件之一是 IOC,IOC 则管理 Bean 的创建和 Bean 之间的依赖注入,对于 Bean 的创建可以通过在 XML 里面使用 <bean/> 标签来 ...

  4. Spring 中常用注解原理剖析

    前言 Spring 框架核心组件之一是 IOC,IOC 则管理 Bean 的创建和 Bean 之间的依赖注入,对于 Bean 的创建可以通过在 XML 里面使用 <bean/> 标签来配置 ...

  5. Mybatis的mapper接口在Spring中实例化过程

    在spring中使用mybatis时一般有下面的配置 <bean id="mapperScannerConfigurer" class="org.mybatis.s ...

  6. 简说Spring中的资源加载

    声明: 本文若有 任何纰漏.错误,请不吝指正!谢谢! 问题描述 遇到一个关于资源加载的问题,因此简单的记录一下,对Spring资源加载也做一个记录. 问题起因是使用了@PropertySource来进 ...

  7. Spring中的Mybatis

    1. 前言 在构建一个web应用时基本的套路就是SSM,其中的M就是Mybatis. Mybatis作为一款开源的ORM框架, 由于其易于上手的特点成为当下比较流行的ORM框架,当然它还有一款插件能够 ...

  8. Spring中各种扩展原理及容器创建原理

    一.BeanFactoryPostProcessor BeanFactory的后置处理器:在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容:所有的bean定义已经保 ...

  9. 面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

随机推荐

  1. 3、组件注册-@ComponentScan-自动扫描组件&指定扫描规则

    3.组件注册-@ComponentScan-自动扫描组件&指定扫描规则 3.1 xml方式 benas.xml 导入context命名空间 <?xml version="1.0 ...

  2. MySQL8 设置大小写 正确步骤

    在安装完成之后,初始化数据库之前,修改 my.cnf 打开mysql配置文件vim /etc/my.cnf 在尾部追加一行lower_case_table_names=1并保存,然后再初始化数据库. ...

  3. @MapperScan和@ComponentScan的区别

    区别 今天在撸SpringBoot的时候,突然对注解产生了混淆,@MapperScan和@ComponentScan都是扫描包,二者之间有什么区别呢? 首先,@ComponentScan是组件扫描注解 ...

  4. 富文本编辑器word

    tinymce是很优秀的一款富文本编辑器,可以去官网下载.https://www.tiny.cloud 这里分享的是它官网的一个收费插件powerpaste的旧版本源码,但也不影响功能使用. http ...

  5. CSPS模拟69-72

    模拟69: T1,稍数学,主要还是dp(转移莫名像背包???),当C开到n2时复杂度为n4,考场上想了半天优化结果发现n是100,n4可过 #include<iostream> #incl ...

  6. c实现单向链表

    实现一个单向链表的:创建.插入.删除.排序(冒泡).逆向.搜索中间节点 #include <iostream> #include <stdio.h> #include < ...

  7. Web开发入门教程:Pycharm轻松创建Flask项目

    Web开发入门教程:Pycharm轻松创建Flask项目 打开Pycharm的file,选择创建新的项目,然后弹出对话框,我们可以看到里面有很多的案例,Flask.Django等等,我们选择生成Fla ...

  8. "数字经济"云安全共测大赛Web-Writeup

    gameapp 这题首先反编译apk,简单看了看代码,主要是有startgame和score两个api,然后用模拟器(手机登不上)安装apk抓了下包,数据经过了rsa加密,所以首先用python实现r ...

  9. Flutter移动电商实战 --(31)列表页_列表切换交互制作

    点击左侧的大类右边的小类也跟着变化 新建provide 要改变哪里就建哪里的provide,我们现在要改变的是右边的商品列表的数组. category_goods_list.dart 这样我们的pro ...

  10. android studio的安装和配置及解决uiautomatorviewer报错

    参考博客:https://www.cnblogs.com/singledogpro/p/9551841.html 安装Android Studio 走了不少弯路,现在整理出来,仅当备忘使用. 首先要先 ...