Spring中BeanDefinitionRegistryPostProcessor接口 -【Spring底层原理】

blogg57

1、概述

上一篇咱们讲到spring中BeanFactoryPostProcessor能够对bean进行修改拓展,Spring中BeanFactoryPostProcessor接口 -【Spring底层原理】,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的一个子接口,那BeanDefinitionRegistryPostProcessor是否是能够对BeanDefinitionRegistry进行修改拓展呢,答案是确定的,那什么是BeanDefinitionRegistry呢,了解BeanDefinitionRegistry,首先得要知道什么是BeanDefinitionjava

【1】BeanDefinitionspring

容器中的每个bean都会有一个对应的BeanDefinition实例,该实例负责保存bean对象的全部必要信息,包括bean对象的class类型、是不是抽象类、构造方法和参数、其它属性等等。数组

【2】BeanDefinitionRegistrymarkdown

BeanDefinition是定义bean的,BeanDefinitionRegistry则是bean定义信息的保存中心,也叫注册中心,保存了bean的全部定义,之后BeanFactory就是按照BeanDefinitionRegistry里面保存的每个bean定义信息建立bean实例。bean是单例仍是多例,bean的类型,bean的ID等信息,都是存在BeanDefinitionRegistry里面。app

综上,BeanDefinitionRegistryPostProcessor就是bean定义注册中心的后置处理器,容许咱们修改拓展bean定义信息的注册中心,在全部bean定义信息将要被加载,bean实例还未建立的时候执行oop

2、实例分析

// 启动测试类
@Test
public void TestMain(){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
    String[] beanNames = applicationContext.getBeanDefinitionNames();
    for (String beanName : beanNames) {
        System.out.println(beanName);
    }
}

// 待注入的bean
public class User {
}

// BeanDefinitionRegistryPostProcessor实现类
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
        System.out.println("bean的数量:"+ beanDefinitionRegistry.getBeanDefinitionCount());
        // 经过bean的构建器生成rootbean
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        beanDefinitionRegistry.registerBeanDefinition("hello",beanDefinition);

    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
        System.out.println("bean的数量:" + configurableListableBeanFactory.getBeanDefinitionCount());
    }
}

// 配置类
@Configuration
@ComponentScan("postprocessor")
public class AppConfig {
}
复制代码

能够看到输出结果以下,从中咱们能够看出:源码分析

  • 先执行postProcessBeanDefinitionRegistry方法,获取到IOC容器中bean的数量为7
  • 而后给Registry里面注册一个hello
  • 再执行postProcessBeanFactory方法,因为上面又注册了一个,因此这里获取到IOC容器中bean的数量为8
  • 等BeanDefinitionRegistryPostProcessor里面的方法都执行完后,再执行BeanFactoryPostProcessor里面的方法

image-20210319140530528

3、源码分析

一样,咱们经过Debug的方式来分析源码,在postProcessBeanDefinitionRegistry方法处打个断点,启动断点调试,根据方法调用栈来进行跟踪:post

image-20210319154228551

经过查看方法调用栈,能够做出以下分析:测试

  • 启动IOC容器调用refresh方法
  • 再依次调用invokeBeanFactoryPostProcessors()——>invokeBeanDefinitionRegistryPostProcessors()方法
  • 在invokeBeanDefinitionRegistryPostProcessors方法中获取到currentRegistryProcessors参数
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    ......
    // 获取到BeanDefinitionRegistryPostProcessor组件
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    var16 = postProcessorNames;
    var9 = postProcessorNames.length;

    for(var10 = 0; var10 < var9; ++var10) {
        ppName = var16[var10];
        if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 获取currentRegistryProcessors参数
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
        }
    }
    
    ......
        while(reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var19 = postProcessorNames;
            var10 = postProcessorNames.length;

            for(int var26 = 0; var26 < var10; ++var26) {
                String ppName = var19[var26];
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 1.在这个方法里面触发postProcessBeanDefinnitionRegistry
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
        }
    // 2.在这个方法里面触发postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
    invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
	......
    // 3.在这个方法里面触发postProcessorBeanFactory方法
    invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
    ......
}
复制代码

从源码能够看到:ui

  • 先获取BeanDefinitionRegistryPostProcessor组件
  • 再按照必定规则(如优先级)加入到currentRegistryProcessors数组中
  • currentRegistryProcessors做为参数传给invokeBeanDefinitionRegistryPostProcessors方法,最后在这个方法执行
  • 下图能够看到此时已经将本身写的MyBeanDefinitionRegistryPostProcessor组件给获取到了

image-20210319155522363

【1】触发BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry

进入invokeBeanDefinitionRegistryPostProcessors方法,能够看到,在这里获取到组件并触发了postProcessBeanDefinitionRegistry:

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
    Iterator var3 = postProcessors.iterator();

    while(var3.hasNext()) {
        BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var3.next();
        StartupStep var10000 = applicationStartup.start("spring.context.beandef-registry.post-process");
        postProcessor.getClass();
        StartupStep postProcessBeanDefRegistry = var10000.tag("postProcessor", postProcessor::toString);
        // 触发postProcessBeanDefinnitionRegistry
        postProcessor.postProcessBeanDefinitionRegistry(registry);
        postProcessBeanDefRegistry.end();
    }
}
复制代码

【2】触发BeanDefinitionRegistryPostProcessor组件的BeanFactoryPostProcessor#postProcessBeanFactory

在invokeBeanDefinitionRegistryPostProcessors方法执行完后,经过invokeBeanFactoryPostProcessors方法执行postProcessBeanFactory,点进源码进行查看:

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    Iterator var2 = postProcessors.iterator();

    while(var2.hasNext()) {
        BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
        StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
        postProcessor.getClass();
        StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
        // 执行postProcessBeanFactory
        postProcessor.postProcessBeanFactory(beanFactory);
        postProcessBeanFactory.end();
    }
}
复制代码

【3】触发其余组件的BeanFactoryPostProcessor#postProcessBeanFactory

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    Iterator var2 = postProcessors.iterator();

    while(var2.hasNext()) {
        BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
        StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
        postProcessor.getClass();
        StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
        // 触发postProcessorBeanFactory方法
        postProcessor.postProcessBeanFactory(beanFactory);
        postProcessBeanFactory.end();
    }

}
复制代码

经过源码能够看到的执行顺序:

  1. 执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
  2. 执行BeanDefinitionRegistryPostProcessor组件的BeanFactoryPostProcessor#postProcessBeanFactory
  3. 执行其余组件的BeanFactoryPostProcessor#postProcessBeanFactory

4、总结

  1. AnnotationConfigApplicationContext:建立IOC对象

  2. refresh()——>invokeBeanFactoryPostProcessors():执行BeanDefinitionRegistryPostProcessor

  3. 从容器中获取到全部的BeanDefinitionRegistryPostProcessor组件

    1. 依次触发全部的postProcessBeanDefinitionRegistry()方法

    2. 再来触发postProcessorBeanFactory()方法BeanFactoryPostProcessor

  4. 再来从容器中找到BeanFactoryPostProcessor组件,而后依次触发postProcessorBeanFactory()方法

从这个总结也能够看出postProcessBeanDefinitionRegistry()方法要先于BeanFactoryPostProcessor()执行

相关文章
相关标签/搜索