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. python以下划线开头的变量和函数的作用

    在python中,我们经常能看到很多变量名以_下划线开头,而且下划线的数量还不一样,那么这些变量的作用到底是什么? 变量名分类: # 以数字.字母开头: 正常的公有变量名a = 1def aa(): ...

  2. PHP实现页面跳转功能

    PHP跳转到指定页面的问题通常都会建设网站需求上看到,比如我们需要从一个页面跳转到另一个页面来实现某个功能或者效果.其实在PHP中进行页面跳转是有多种方法的,那么这篇文章就给大家介绍下,有哪些方法可以 ...

  3. 014_linux驱动之_信号符号名、描述和它们的信号值

    符号名 信号值 描述 是否符合POSIX SIGHUP 1 在控制终端上检测到挂断或控制线程死 亡 是 SIGINT 2 交互注意信号 是 SIGQUIT 3 交 互中止信号 是 SIGILL 4 检 ...

  4. 浏览器事件环(EventLoop)

    1. 基础知识 1. js语言特点 1. js语言是单线程语言,主线程是单线程.如UI渲染,脚本加载是主线程任务. 2. js语言采用事件循环(EventLoop)机制. 2. 同步任务: 不被引擎挂 ...

  5. at/crontab

    at yum -y install at systemctl start atd 增加任务 增加任务的第三行是 是ctrl+D 表示的是退出 第四行是系统提示任务执行的时间 任务查询 atq 任务删除 ...

  6. Screen 用法简述

    Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换.GNU Screen可以看作是窗口管理器的命令行界面版本.它提 ...

  7. sqlserver 存储过程的新建与执行

    if Exists(select * from sysobjects where NAME = 'insert_custominfo' and type='P') drop procedure ins ...

  8. java微服务简介与实战

    今年做了一段时间的可见光.ceph存储,后端开发微服务项目,在这记录点东西,也方便大家借鉴查找. springboot的项目实例:https://github.com/ityouknow/spring ...

  9. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

  10. 以太坊geth区块链私链建立

      以太坊geth区块链私链建立 geth的github https://github.com/ethereum/go-ethereum 下载最新(1.8)的geth,windows下安装很简单 关于 ...