Spring 的发展历史较为悠久,因此很多资料还在讲解它较旧的实现,这里出于怀旧的原因,把它们都列出来,供大家参考
-  DefaultListableBeanFactory,是 BeanFactory 最重要的实现,像控制反转和依赖注入功能,都是它来实现 
-  ClassPathXmlApplicationContext,从类路径查找 XML 配置文件,创建容器(旧) 
-  FileSystemXmlApplicationContext,从磁盘路径查找 XML 配置文件,创建容器(旧) 
-  XmlWebApplicationContext,传统 SSM 整合时,基于 XML 配置文件的容器(旧) 
-  AnnotationConfigWebApplicationContext,传统 SSM 整合时,基于 java 配置类的容器(旧) 
-  AnnotationConfigApplicationContext,Spring boot 中非 web 环境容器(新) 
-  AnnotationConfigServletWebServerApplicationContext,Spring boot 中 servlet web 环境容器(新) 
-  AnnotationConfigReactiveWebServerApplicationContext,Spring boot 中 reactive web 环境容器(新) 
另外要注意的是,后面这些带有 ApplicationContext 的类都是 ApplicationContext 接口的实现,但它们是组合了 DefaultListableBeanFactory 的功能,并非继承而来
在这里,我们以BeanFactory 最重要的实现DefaultListableBeanFactory为例,来讲解BeanFactory的实现:
  
   - 
    
     
    
    
       
      //创建实例对象
     
    
- 
    
     
    
    
        
      DefaultListableBeanFactory 
      beanFactory 
      = 
      new 
      DefaultListableBeanFactory();
     
    
因为刚创建好的对象是没有任何bean的,所以我们要进行添加bean,准备三个基本的Config类,用来添加bean
  
   - 
    
     
    
    
       
      @Configuration
     
    
- 
    
     
    
    
         
      static 
      class 
      Config {
     
    
- 
    
     
    
    
             
      @Bean
     
    
- 
    
     
    
    
             
      public Bean1 
      bean1
      () {
     
    
- 
    
     
    
    
                 
      return 
      new 
      Bean1();
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      @Bean
     
    
- 
    
     
    
    
             
      public Bean2 
      bean2
      () {
     
    
- 
    
     
    
    
                 
      return 
      new 
      Bean2();
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      @Bean
     
    
- 
    
     
    
    
             
      public Bean3 
      bean3
      () {
     
    
- 
    
     
    
    
                 
      return 
      new 
      Bean3();
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      @Bean
     
    
- 
    
     
    
    
             
      public Bean4 
      bean4
      () {
     
    
- 
    
     
    
    
                 
      return 
      new 
      Bean4();
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
     
          }
     
    
- 
    
     
    
    
       
      static 
      class 
      Bean1 {
     
    
- 
    
     
    
    
             
      private 
      static 
      final 
      Logger 
      log 
      = LoggerFactory.getLogger(Bean1.class);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      public 
      Bean1
      () {
     
    
- 
    
     
    
    
     
                  log.debug(
      "构造 Bean1()");
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      @Autowired
     
    
- 
    
     
    
    
             
      private Bean2 bean2;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      public Bean2 
      getBean2
      () {
     
    
- 
    
     
    
    
                 
      return bean2;
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
       
      static 
      class 
      Bean2 {
     
    
- 
    
     
    
    
             
      private 
      static 
      final 
      Logger 
      log 
      = LoggerFactory.getLogger(Bean2.class);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
             
      public 
      Bean2
      () {
     
    
- 
    
     
    
    
     
                  log.debug(
      "构造 Bean2()");
     
    
- 
    
     
    
    
     
              }
     
    
- 
    
     
    
    
     
          }
     
    
 创建config的beanDefinition,用来加入bean工厂里,以后有bean工厂来进行管理
  
   - 
    
     
    
    
         
      AbstractBeanDefinition 
      beanDefinition 
      =
     
    
- 
    
     
    
    
     
                      BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope(
      "singleton").getBeanDefinition();
     
    
注册beanDefinition
    beanFactory.registerBeanDefinition("config", beanDefinition);ok,bean工厂里面就有了一个叫config的bean,单例模式。
测试一波,来看看这个bean工厂里面有多少个beanDefinition
  
   - 
    
     
    
    
        
      for (String name : beanFactory.getBeanDefinitionNames()) {
     
    
- 
    
     
    
    
     
                  System.out.println(name);
      //Config
     
    
- 
    
     
    
    
     
              }
     
    
看到这里,我们可能会有个疑问,因为在配置类中,我们不是加了@Bean的注解吗?所以容器应该有bean1和bean2,但输出的结果却只有config,为什么呢?
输出结果就说明这个@Configuration,@Bean注解没有被解析,也就是这个BeanFactory它缺少了解析这些注解的能力,功能并不完整。
那么我们怎么才能让它的功能完整,可以解析这些注解呢? 有其他的类来提供解析这些注解的能力
  
   - 
    
     
    
    
        
      //给BeanFactory 添加一些常用的后处理器
     
    
- 
    
     
    
    
     
           AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
     
    
这些后处理器就是对beanFactory进行功能上的扩展,解决不能解析注解的问题。
此时,我们再来输出结果一波:
  
   - 
    
     
    
    
        
      for (String name : beanFactory.getBeanDefinitionNames()) {
     
    
- 
    
     
    
    
     
                  System.out.println(name);
     
    
- 
    
     
    
    
     
              }
     
    

多了一些spring内置的bean后处理器,第一个是用来处理@Configuration注解,将其配置类里面的定义的bean信息补充到beanFactory中
这个时候,输出的结果并没有bean1和bean2,这是为什么呢?那是因为我们这是添加了后处理器,但并没有让它运行
  
   - 
    
     
    
    
       
      // BeanFactory 后处理器主要功能,补充了一些 bean 定义
     
    
- 
    
     
    
    
             
      // bean 的定义(class, scope, 初始化, 销毁) 
     
    
- 
    
     
    
    
       
      //解析 @Configuration @Bean注解
     
    
- 
    
     
    
    
     
              beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
     
    
- 
    
     
    
    
               
      //执行BeanFactory的后处理器
     
    
- 
    
     
    
    
     
              beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
     
    
- 
    
     
    
    
     
              });
     
    

ok,此刻我们看到输出结果有bean1和bean2,؏؏☝ᖗ乛◡乛ᖘ☝؏؏
我们将bean1和bean2添加到bean工厂里了,那么可不可以拿出来用呢?我们来试试看:
 System.out.println(beanFactory.getBean(Bean1.class).getBean2());
bean1可以拿到,但是bean2等于null,这是为什么呢?@Autowired依赖注入没有被解析。
这也是bean工厂的扩展功能,是由其他的后处理器通过的解析功能,用ben的后处理器来完成实现,来,看代码:
  
   - 
    
     
    
    
          
      // Bean 后处理器, 针对 bean 的生命周期的各个阶段提供扩展, 例如 @Autowired @Resource ...
     
    
- 
    
     
    
    
     
              beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
     
    
- 
    
     
    
    
                     
      //获取比较器(单例)
     
    
- 
    
     
    
    
     
                      .sorted(beanFactory.getDependencyComparator())
     
    
- 
    
     
    
    
     
                      .forEach(beanPostProcessor -> {
     
    
- 
    
     
    
    
     
                  System.out.println(
      ">>>>" + beanPostProcessor);
     
    
- 
    
     
    
    
               
      //建立bean工厂与后处理器的联系
     
    
- 
    
     
    
    
     
                  beanFactory.addBeanPostProcessor(beanPostProcessor);
     
    
- 
    
     
    
    
     
              });
     
    
ok,؏؏☝ᖗ乛◡乛ᖘ☝؏؏
bean的后处理器有多个,功能不同,解析的注解也不同,来看源代码:

bean 后处理器会有排序的逻辑,来看排序规则:
  
   - 
    
     
    
    
     
           System.out.println(
      "Common:" + (Ordered.LOWEST_PRECEDENCE - 
      3));
      // 2147483644
     
    
- 
    
     
    
    
     
              System.out.println(
      "Autowired:" + (Ordered.LOWEST_PRECEDENCE - 
      2));
      // 2147483645
     
    
所以common排在前面,Autowired排在后面。
总结:
beanFactory 不会做的事 :
                  1. 不会主动调用 BeanFactory 后处理器
                    2. 不会主动添加 Bean 后处理器
                    3. 不会主动初始化单例
                    4. 不会解析beanFactory 还不会解析 ${ } 与 #{ }
bean 后处理器会有排序的逻辑
转载:https://blog.csdn.net/qq_61313896/article/details/128748490
 
					