【Spring源码解析】BeanFactoryPostProcessor【相关类】源码解析

news/2024/7/3 5:43:50

1 BeanFactoryPostProcessor作用

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
   /**
    * 可以修改容器Bean内部的定义信息,全部的bean definitions会加载但是bean没有被实例化
    */
   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

1.1 代码

(1) Student

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private String name;

}

(2) 配置文件

@ComponentScan("com.spring")
@Configuration
public class SpringConfig {
    @Primary
    @Bean
    public Student zhangsan(){
        return new Student("张三");
    }
    @Bean
    public Student lisi(){
        return new Student("李四");
    }
}

(3) 主程序

public class SpringApplicationContext {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Student bean = context.getBean(Student.class);
        System.out.println(bean.getName());
    }
}

在这里插入图片描述

1.2 添加配置文件

@Configuration
public class ZrsBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("###############postProcessBeanFactory#################");
        System.out.println("bean 的数量为:"+beanFactory.getBeanDefinitionCount());
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        System.out.println("BeanName为:"+ Arrays.asList(beanDefinitionNames));
        //把李四设置成Primary
        BeanDefinition lisi = beanFactory.getBeanDefinition("lisi");
        lisi.setPrimary(true);
        //把张三设置成非Primary
        BeanDefinition zhangsan = beanFactory.getBeanDefinition("zhangsan");
        zhangsan.setPrimary(false);
    }
}

运行主程序:
在这里插入图片描述

2 BeanDefinitionRegistryPostProcessor

2.1 类图

在这里插入图片描述

2.2 源代码

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
   /**
    * BeanDefinitionRegistryPostProcessor扩充了BeanFactoryPostProcessor功能
    * BeanDefinitionRegistry可以给工厂中注册Bean
    */
   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

2.3 代码

(1) 配置文件

@ComponentScan("com.spring")
@Configuration
public class SpringConfig {

}

(2) pojo

@Data
public class HelloWorld {

}

(3) ZrsBeanDefinitionRegistryPostProcessor

@Configuration
public class ZrsBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("postProcessBeanDefinitionRegistry:");
        System.out.println("bean 的数量为:"+registry.getBeanDefinitionCount());
        RootBeanDefinition rootBeanDefinition=new RootBeanDefinition(HelloWorld.class);
        registry.registerBeanDefinition("helloworld", rootBeanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory:");
        System.out.println("bean 的数量为:"+beanFactory.getBeanDefinitionCount());
    }
}

(4) 主程序

public class SpringApplicationContext {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        HelloWorld bean = context.getBean(HelloWorld.class);
        System.out.println(bean);
    }
}

(5) 结果
分析:BeanDefinitionRegistryPostProcessor加强BeanFactoryPostProcessor,并且先运行postProcessBeanDefinitionRegistry,在运行postProcessBeanFactory。
在这里插入图片描述

4 源码调试

在这里插入图片描述
(1) 分析方法栈
在这里插入图片描述
(2) IOC初始化调用位置 AbstractApplicationContext.,refresh方法
在这里插入图片描述(3) PostProcessorRegistrationDelegate invokeBeanFactoryPostProcessors 源码分析

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
 
   Set<String> processedBeans = new HashSet<>();
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      //1 存储BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor的处理器
      List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
      //2 遍历beanFactoryPostProcessors把BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor分开
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            //2.1 执行postProcessBeanDefinitionRegistry,并且添加BeanDefinitionRegistryPostProcessor
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            //2.2 添加BeanFactoryPostProcessor
            regularPostProcessors.add(postProcessor);
         }
      }
      // 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.
      //3 当前的currentRegistryProcessors  
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      //4 获取BeanDefinitionRegistryPostProcessor.class   
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      //5 找出实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor  
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      //6 排序,添加,并且运行当前所有currentRegistryProcessors的postProcessBeanDefinitionRegistry方法,清空currentRegistryProcessors
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      //7 重新获取,防止上文postProcessBeanDefinitionRegistry的方法添加了新的BeanDefinitionRegistryPostProcessor
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      //8 分类,获取实现Ordered的接口的BeanDefinitionRegistryPostProcessor
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      //9 添加,注册,调取当前BeanDefinitionRegistryPostProcessor所有的postProcessBeanDefinitionRegistry方法,清空currentRegistryProcessors  
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      //10 处理没有实现Ordered, PriorityOrdered接口的BeanDefinitionRegistryPostProcessor   
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         //循环获取,防止BeanDefinitionRegistryPostProcessor添加新的BeanDefinitionRegistryPostProcessor对象    
         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.
      //11 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法和BeanFactoryPostProcessor的postProcessBeanFactory方法
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }
   else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }
   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   //12 获取BeanFactoryPostProcessor.class类型beannames 
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   //13 存储PriorityOrdered.class、Ordered、双非的类名
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   //14 分类
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   //15 排序,调用BeanFactoryPostProcessor的postProcessBeanFactory类
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   //16 存储,排序,调用BeanFactoryPostProcessor实现了Order的postProcessBeanFactory类
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
   // Finally, invoke all other BeanFactoryPostProcessors.
   //17 最后调用双非的BeanFactoryPostProcessor的postProcessBeanFactory方法
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

5 ConfigurationClassPostProcessor

作用:注册Bean的信息,但不是实例化Bean
在这里插入图片描述

5.1 引入时机

(1) AnnotationConfigApplicationContext 构造
在这里插入图片描述
(2) AnnotationConfigApplicationContext() 构造
在这里插入图片描述
(3)AnnotatedBeanDefinitionReader 构造
在这里插入图片描述
(4) AnnotatedBeanDefinitionReader 构造
在这里插入图片描述
(5) AnnotationConfigUtils registerAnnotationConfigProcessors
在这里插入图片描述

(6) AnnotationConfigUtils registerAnnotationConfigProcessors
在这里插入图片描述

5.2 作用

(1) ConfigurationClassPostProcessor 实现了 PriorityOrdered 所以是最先调用

(2) 调试 PostProcessorRegistrationDelegate invokeBeanFactoryPostProcessors
在这里插入图片描述
(3) PostProcessorRegistrationDelegate invokeBeanDefinitionRegistryPostProcessors
在这里插入图片描述
(4) ConfigurationClassPostProcessor postProcessBeanDefinitionRegistry
在这里插入图片描述
(5) ConfigurationClassPostProcessor processConfigBeanDefinitions
在这里插入图片描述
(6) ConfigurationClassBeanDefinitionReader loadBeanDefinitions
在这里插入图片描述


http://www.niftyadmin.cn/n/4556834.html

相关文章

怎样才可以编程序

||| 编程序需要编程软件的 再把MFC学好的话 我只能这样告诉你了 ||| 你已经学了C 以上建议 碰到问题查帮助;久而久之 里面还包含实用的例子;边学边做项目 很容易就可以找到你想要的答案 你就可以查看里面帮助文件;使用索引和查找功能 你可以到CSDN 上面收集另外 VF C语言 模拟电…

Django 模型层之多表操作

一.创建模型 实例: 作者表:拥有字段:姓名(name),性别(sex),该表与书籍表之间为多对多的关系 作者详情表:拥有字段:地址(addr),手机号(phone),该表与作者表之间为一对一的关系 出版社表:拥有字段:名字(name),地址(addr),该表与书籍表之间为一对多的关系 书籍表:拥有字段:书名(na…

【Spring源码解析】 IOC 初始化流程分析

1 .AbstractApplicationContext prepareBeanFactory Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新前预处理prepareRefresh();//获取beanFactory实例。(DefaultListableBeanFactory)Conf…

c.k.沉珂 的所有资料

证明你是光明与正义的化身啊 是个双性恋 跟男生是谈精神上的恋爱 和女性的有肉体上的交缠(她日记里写的)她很爱她的爸爸妈妈 不想被遗忘 不想被伤害 有玩血和自残的习惯 经常用刀子把自己划的遍体鳞伤 用很多针管抽自己的血 每天都会一个人哭泣 她精神上特别痛苦 曾经一次性打过…

怎样实现 C 盘的数据还在 我想增大C盘 我不想再装系统了

用PMagic把C盘大小改一下就行了 数据不会丢失

【SpringMVC源码解析】 ServletContainerInitializer SpringMVC源码入口解析

1 ServletContainerInitializer 在web容器启动时为提供给第三方组件机会做一些初始化的工作&#xff0c;servlet规范(JSR356)中通过ServletContainerInitializer实现此功能。每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名…

CountDownLatch 源码讲解

CountDownLatch 源码讲解老规矩&#xff0c;先翻译源码。 CountDownLatch 是一种同步辅助工具&#xff0c;允许一个或多个线程等待其他线程中正在执行的一组操作完成。 CountDownLatch是用给定的count参数初始化实例。 await方法会一直阻塞到当前计数为零&#xff0c;当调用c…

高手进 C语言该怎么学起才是最好啊

因为C语言最简单 C语言足够低级 就不要涉足计算机领域 除了“指针” 非常非常地贴近计算机的底层结构 但也许并不需要“面向对象”、“模板”、“函数重载”等等一大堆概念 不必思考应该学什么 而“指针” C语言没有真正意义上的难点 不会让你迷失在概念的汪洋大海 如果你对操作…