PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors

PostProcessorRegistrationDelegate #invokeBeanFactoryPostProcessors

总结:
  • 先处理BeanFactory的PostProcessor属性中的BeanDefinitionPostProcessor
  • 再处理BeanFactory的BeanDefinitionMap中的BeanDefinitionPostProcessor(实例化Bean,然后调用方法)
  • 在处理因为上面实例化后的BeanDefinitionPostProcessor而导入的新的BeanDefinitionPostProcessor

然后统一处理上面所有的BeanFactoryPostProcessor实现方法

最后处理BeanFactory的BeanDefinitionMap中的BeanFactoryPostProcessor组件。

没有看懂整个过程是理解不了的,看完源码再回来理解这个总结。

代码总览
这里代码量很大,并且有些分支值得深究,在调试的时候很容易迷失到代码中,所以很有必要做个总结与概括。

在读源代码的时候最深刻的感悟就是:一个类或者方法的命名是多么重要,事实证明只有在真正理解了类或方法的功能你才真正理解了它的命名
invokeBeanFactoryPostProcessors

总的来说,这个函数其实只做了一件事,让BeanFactoryPostProcessor 在此时发挥它的作用

在这里插入图片描述

函数入参

这个函数确实代码量很大,但是有一点比较好,那就是涉及的类不多,

在这里插入图片描述
有必要对着三个BeanFactoryPostProcessor介绍一下
前两个是BeanDefinitionRegistryPostProcessor的实现类
后一个是BeanFactoryPostProcessor的实现类

其实BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它们着重的功能不同。

几个PostProcessor的区别

第一步: 对BeanDefinitionRegistryPostProcessor实现类的调用

在这里插入图片描述

第一个if,判断beanFactory 是否是BeanDefinitionRegistry类型,当然是,所以走这条路
80行代码。

1.1 对BeanDefinitionRegistryPostProcessor的处理
总结: 做了两件事
(1) 对入参BeanFactoryPostProcessors进行分类,上面已经提到,它们分别代表两种不同的实现类,分别进行判断,并用变量存起来后续处理
(2)如果是BeanDefinitionRegistryPostProcessor,调用它实现接口BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry方法。直接在此处发挥它的作用

前两个BeanFactoryPostProcessor作为BeanDefinitionRegistryPostProcessor的实现类已经调用了该方法,第3个BeanFactoryPostProcessor因为是普通BeanFactoryPostProcessor所以放入regularPostProcessors。
在这里插入图片描述

1.2 对beanFactory中注册的BeanDefinition进行处理——查看是否匹配BeanDefinitionRegistryPostProcessor类型

总结:在BeanFactory中的BeanDefinitionMaps里存放的names可能是别名(其实不用可能org.springframework.context.annotation.internalConfigurationAnnotationProcessor就是个别名),而它本身定义的BeanDefinition可能是个BeanDefinitionRegistryPostProcessor类型,之前讲到了invokeBeanFactoryPostProcessors方法中要执行完BeanFactoryPostProcessor的调用,所以在BeanFactory中的BeanDefinitionRegistryPostProcessor也拿出来,并且让它开始工作。

以下所对应的BeanDefinitionRegistryPostProcessor是ConfigurationClassPostProcessor,我们就是把它找出来。
在这里插入图片描述
此时有BeanDefinitionMap中有7个,但是只有一个匹配BeanDefinitionRegistryPostProcessor,就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor(是大名鼎鼎的ConfigurationClassPostProcessor的bean别名)
在这里插入图片描述

之后就是对该bean的实例化,好了,现在internalConfigurationAnnotationProcessor已经被处理了,放入processedBeans。
在这里插入图片描述

1.3 经过上面,我们已经找到了新的BeanDefinitionRegistryPostProcessor,开始进行处理

很清晰的步骤:
(1)把它和之前的BeanDefinitionRegistryPostProcessor放到一块
(2)让它开始工作(执行实现的postProcessBeanDefinitionRegistry方法)

在这里插入图片描述
显然它也不负众望,执行实现BeanDefinitionRegistryPostProcessor抽象类的方法
在这里插入图片描述

1.4 为什么执行多次?

可以看到这里又去BeanDefinitionMap中寻找BeanDefinitionRegistryPostProcessor类型,原因可能是在执行上述BeanDefinitionRegistryPostProcessor之后可能导致BeanFactory新增相关BeanDefinition,要一直处理直到这些BeanDefinitionRegistryPOSTProcessor类型都调用了实现方法。
在这里插入图片描述

1.5 还有第三遍?

在这里插入图片描述

invokeBeanFactoryPostProcessors BeanFactoryPostProcessor工作
 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   
        Set<String> processedBeans = new HashSet();
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        if (beanFactory instanceof BeanDefinitionRegistry) {
   
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
            Iterator var6 = beanFactoryPostProcessors.iterator
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java.lang.NoClassDefFoundError: org/springframework/aot/AotDetector at org.mybatis.spring.mapper.ClassPathMapperScanner.<init>(ClassPathMapperScanner.java:91) ~[mybatis-spring-3.0.2.jar:3.0.2] at org.mybatis.spring.mapper.MapperScannerConfigurer.postProcessBeanDefinitionRegistry(MapperScannerConfigurer.java:363) ~[mybatis-spring-3.0.2.jar:3.0.2] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.27.jar:5.3.27] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:142) ~[spring-context-5.3.27.jar:5.3.27] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:748) ~[spring-context-5.3.27.jar:5.3.27] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.27.jar:5.3.27] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.12.jar:2.7.12] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.12.jar:2.7.12] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.12.jar:2.7.12] at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.12.jar:2.7.12] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.12.jar:2.7.12] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.12.jar:2.7.12] at com.lx.MybatisPlusApplication.main(MybatisPlusApplication.java:10) ~[classes/:na] Caused by: java.lang.ClassNotFoundException: org.springframework.aot.AotDetector at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na] ... 13 common frames omitted
最新发布
07-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值