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

柔情只为你懂 2021-09-21 21:34 355阅读 0赞

目录

一、概述

二、实例分析

三、源码分析

四、总结


一、概述

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

【1】BeanDefinition

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

【2】BeanDefinitionRegistry

BeanDefinition是定义bean的,BeanDefinitionRegistry则是bean定义信息的保存中心,也叫注册中心,保存了bean的所有定义,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例。bean是单例还是多例,bean的类型,bean的ID等信息,都是存在BeanDefinitionRegistry里面。

综上,BeanDefinitionRegistryPostProcessor就是bean定义注册中心的后置处理器,允许我们修改拓展bean定义信息的注册中心,在所有bean定义信息将要被加载,bean实例还未创建的时候执行

二、实例分析

  1. // 启动测试类
  2. @Test
  3. public void TestMain(){
  4. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  5. String[] beanNames = applicationContext.getBeanDefinitionNames();
  6. for (String beanName : beanNames) {
  7. System.out.println(beanName);
  8. }
  9. }
  10. // 待注入的bean
  11. public class User {
  12. }
  13. // BeanDefinitionRegistryPostProcessor实现类
  14. @Component
  15. public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
  16. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
  17. System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
  18. System.out.println("bean的数量:"+ beanDefinitionRegistry.getBeanDefinitionCount());
  19. // 通过bean的构建器生成rootbean
  20. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
  21. beanDefinitionRegistry.registerBeanDefinition("hello",beanDefinition);
  22. }
  23. public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
  24. System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
  25. System.out.println("bean的数量:" + configurableListableBeanFactory.getBeanDefinitionCount());
  26. }
  27. }
  28. // 配置类
  29. @Configuration
  30. @ComponentScan("postprocessor")
  31. public class AppConfig {
  32. }

可以看到输出结果如下,从中我们可以看出:

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

image-20210319140530528

三、源码分析

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

image-20210319154228551

通过查看方法调用栈,可以作出如下分析:

  • 启动IOC容器调用refresh方法
  • 再依次调用invokeBeanFactoryPostProcessors()——>invokeBeanDefinitionRegistryPostProcessors()方法
  • 在invokeBeanDefinitionRegistryPostProcessors方法中获取到currentRegistryProcessors参数
  1. public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  2. ......
  3. // 获取到BeanDefinitionRegistryPostProcessor组件
  4. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  5. var16 = postProcessorNames;
  6. var9 = postProcessorNames.length;
  7. for(var10 = 0; var10 < var9; ++var10) {
  8. ppName = var16[var10];
  9. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  10. // 获取currentRegistryProcessors参数
  11. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  12. processedBeans.add(ppName);
  13. }
  14. }
  15. ......
  16. while(reiterate) {
  17. reiterate = false;
  18. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  19. String[] var19 = postProcessorNames;
  20. var10 = postProcessorNames.length;
  21. for(int var26 = 0; var26 < var10; ++var26) {
  22. String ppName = var19[var26];
  23. if (!processedBeans.contains(ppName)) {
  24. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  25. processedBeans.add(ppName);
  26. reiterate = true;
  27. }
  28. }
  29. sortPostProcessors(currentRegistryProcessors, beanFactory);
  30. registryProcessors.addAll(currentRegistryProcessors);
  31. // 1.在这个方法里面触发postProcessBeanDefinnitionRegistry
  32. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
  33. currentRegistryProcessors.clear();
  34. }
  35. // 2.在这个方法里面触发postProcessBeanFactory方法
  36. invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
  37. invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
  38. ......
  39. // 3.在这个方法里面触发postProcessorBeanFactory方法
  40. invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
  41. ......
  42. }

从源码可以看到:

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

image-20210319155522363

【1】触发BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry

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

  1. private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
  2. Iterator var3 = postProcessors.iterator();
  3. while(var3.hasNext()) {
  4. BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var3.next();
  5. StartupStep var10000 = applicationStartup.start("spring.context.beandef-registry.post-process");
  6. postProcessor.getClass();
  7. StartupStep postProcessBeanDefRegistry = var10000.tag("postProcessor", postProcessor::toString);
  8. // 触发postProcessBeanDefinnitionRegistry
  9. postProcessor.postProcessBeanDefinitionRegistry(registry);
  10. postProcessBeanDefRegistry.end();
  11. }
  12. }

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

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

  1. private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
  2. Iterator var2 = postProcessors.iterator();
  3. while(var2.hasNext()) {
  4. BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
  5. StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
  6. postProcessor.getClass();
  7. StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
  8. // 执行postProcessBeanFactory
  9. postProcessor.postProcessBeanFactory(beanFactory);
  10. postProcessBeanFactory.end();
  11. }
  12. }

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

  1. private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
  2. Iterator var2 = postProcessors.iterator();
  3. while(var2.hasNext()) {
  4. BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
  5. StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
  6. postProcessor.getClass();
  7. StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
  8. // 触发postProcessorBeanFactory方法
  9. postProcessor.postProcessBeanFactory(beanFactory);
  10. postProcessBeanFactory.end();
  11. }
  12. }

通过源码可以看到的执行顺序:

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

四、总结

  1. AnnotationConfigApplicationContext:创建IOC对象
  2. refresh()——>invokeBeanFactoryPostProcessors():执行BeanDefinitionRegistryPostProcessor
  3. 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件

    1. 依次触发所有的postProcessBeanDefinitionRegistry()方法
    2. 再来触发postProcessorBeanFactory()方法BeanFactoryPostProcessor
  4. 再来从容器中找到BeanFactoryPostProcessor组件,然后依次触发postProcessorBeanFactory()方法

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

发表评论

表情:
评论列表 (有 0 条评论,355人围观)

还没有评论,来说两句吧...

相关阅读