spring-ioc-容器初始化(上)

太阳每天都是新的,你是否每天都在努力。

本文会涉及到三个方面

1.BeanDefinition

2.BeanFactoryPostProcessor(ConfigurationClassPostProcessor)

3.BeanDefinitionMap的填充-->BeanDefinitionMap.put(beanName,BeanDefinition);

我们先来了解官网对spring容器的说明 

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-basics

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.

Several implementations of the ApplicationContext interface are supplied with Spring. In stand-alone applications, it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the traditional format for defining configuration metadata, you can instruct the container to use Java annotations or code as the metadata format by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.

org.springframework.context.ApplicationContext接口代表Spring IoC容器,并负责实例化,配置和组装Bean。容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。配置元数据以XML,Java批注或Java代码表示。它使您能够表达组成应用程序的对象以及这些对象之间的丰富相互依赖关系。

ApplicationContextSpring提供了该接口的几种实现。在独立应用程序中,通常创建ClassPathXmlApplicationContext 或的实例 FileSystemXmlApplicationContext。尽管XML是定义配置元数据的传统格式,但是您可以通过提供少量XML配置来声明性地启用对这些其他元数据格式的支持,从而指示容器将Java注释或代码用作元数据格式。

下图显示了Spring的工作原理的高级视图。您的应用程序类与配置元数据结合在一起,因此,在ApplicationContext创建和初始化后,您将拥有一个完全配置且可执行的系统或应用程序。

这个图已经说明的非常清楚了,通过spring容器将我们的业务类和元数据结合在一起生产出来的就是一个spring bean了。

 我们先看下spring容器的继承图(简洁版)

我们正常实例化一个容器最多用到的就是这三个

ClassPathXmlApplicationContext  

AnnotationConfigApplicationContext

FileSystemXmlApplicationContext

上面根据官网对 spring容器做了一个简单的介绍

我们现在回到正题 BeanDefinition 是什么。上面的图中提到了一个元数据,这个 BeanDefinition 就是一个元数据,是对一个bean的描述,正如 Java 中用 class 对 object 进行描述一样,而 spring 中为什么不用 class 对 bean 进行描述而要用 beanDefinition呢,因为 class 中不包括元数据及其它需要的属性,class 属性不够用了。而根据不同的方法创建的 bean那么它的元数据也是不一样的。

我们先看 beanDefiniton 的一个简单关系继承图(有删减)

特别说明一点,最新的 spring源码 中已经没有使用 ChildBeanDefinition 因为被 GenericBeanDefinition 代替了。

再看一看继承图的属性

这个属性可以对照源码注释看看(spring命名规范-可望文生义),都是对bean元数据的描述,这些属性都是 class 所没有的。  
看完这个图我们再看下面的一个例子。

public class TestMain {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
		ClassPathXmlApplicationContext ac1 = new ClassPathXmlApplicationContext("classpath:spring2.xml");
		System.out.println("<bean></bean>:"+ac1.getBeanFactory().getBeanDefinition("userBo").getClass().getSimpleName());
		System.out.println("@Configuration:"+ac.getBeanDefinition("appConfig").getClass().getSimpleName());
		System.out.println("@Component:"+ac.getBeanDefinition("personBo").getClass().getSimpleName());
		System.out.println("@Bean:"+ac.getBeanDefinition("createMenuImplBo").getClass().getSimpleName());
	}
}

其结果如下:
<bean></bean>:GenericBeanDefinition
@Configuration:AnnotatedGenericBeanDefinition
@Component:ScannedGenericBeanDefinition
@Bean:ConfigurationClassBeanDefinition

根据上面的继承图可以说只有三种 BeanDefinition 对象的元数据。那么这三种类型的 BeanDefinition 是何时创建的 以及何时存入 BeanDefinitionMap中的呢。

spring容器启动的时候会扫描,根据不同的注解解析到不用的 BeanDefinition 中

那么spring容器扫描做了什么呢

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
   private final AnnotatedBeanDefinitionReader reader;
   private final ClassPathBeanDefinitionScanner scanner;
   /**
    * Create a new AnnotationConfigApplicationContext that needs to be populated
    * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
    */
   public AnnotationConfigApplicationContext() {
      //首先会调用父类的构造方法初始化DefaultListableBeanFactory对象
      this.reader = new AnnotatedBeanDefinitionReader(this);//初始化注解读取器
      this.scanner = new ClassPathBeanDefinitionScanner(this);//初始化扫描器
   }
}
public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();//初始化bean工厂
}

我们顺便看看beanFactory的继承图 发现 DefaultListableBeanFactory 对象 功能是最全的一个呈现出一种通吃的状态

再来看看 DefaultListableBeanFactory 的属性图

我们需要的BeanDefinitionMap就在里面当然其它的属性也很重要我们来看看

/** Map from dependency type to corresponding autowired value. */
//从依赖类型映射到相应的自动获取值
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

/** Map of bean definition objects, keyed by bean name. */
//bean定义对象的映射,由bean名称键控
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

/** Map of singleton and non-singleton bean names, keyed by dependency type. */
//单例和非单例bean名称的映射,由依赖项类型键控
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

/** Map of singleton-only bean names, keyed by dependency type. */
//单例bean名称的映射,由依赖项类型键控
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

/** List of bean definition names, in registration order. */
//bean定义名称列表,按注册顺序排列
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

在介绍这几种注解解析之前我们先来看看下面的内容
我们现在介绍第二个点 BeanFactoryPostProcessor bean工厂的后置处理器(spring-mybatis就用放到了这个处理器来扩展的),依然先看继承图

这次看到的是 ConfigurationClassPostProcessor 对象通吃了这一条线,重写了两个方法(非常关键)

BeanDefinitionRegistryPostProcessor#
//在其之后修改应用程序上下文的内部bean定义注册表,标准的初始化。所有常规的bean定义都会被加载,
//但是还没有实例化bean。这允许进一步添加,在进入下一个后期处理阶段之前定义bean。
//应用程序上下文使用的bean定义注册表
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
 
//BeanFactoryPostProcessor#
//根据应用程序上下文的标准修改它的内部bean工厂初始化。将加载所有bean定义,但不加载bean
//将已经被实例化。这允许覆盖或添加属性,即使是急于初始化的bean。
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

spring应用专栏中有提到过这三个处理器的用法(有瑕疵,不完整)直接就是可以对beanFactory中的BeanDefinition做修改

spring beanFactory后置处理器-BeanFactoryPostProcessor

spring 核心后置处理器-BeanDefinitionRegistryPostProcessor

spring 核心后置处理器-ConfigurationClassPostProcessor

我们现在在代码中加入两个类去空实现这两个接口并配合自定义注解和另外一个接口ImportSelector,顺便看一下这个处理器及子类的执行时机

下面是测试代码环境

业务类(配置类)一共八个如下:

public class MenuImpl {//@Bean 注解
}
public class ServiceBo {//ImportSelector
}
public class UserBo{//xml
}
@Component
public class PersonBo {//@Component注解
	@Bean
	public AServiceBo createAServiceBo(){
		return new AServiceBo();
	}

	@Bean
	public BServiceBo createBServiceBo(){
		return new BServiceBo();
	}
}
public class AServiceBo {//@Bean注解
}
public class BServiceBo {//@Bean注解
}
@Component
public class TestBo {//@Component注解
}

配置类

@Configuration
@ComponentScan("org.springframework.waf.*")
@BeanFactoryPostProcessorAnno
@BeanDefinitionRegistryPostProcessorAnno
@ImportSelectorAnno
public class AppConfig {//@Configuration注解

	@Bean
	public MenuImpl createMenuImplBo(){
		MenuImpl staticMenuImplBo = createStaticMenuImplBo();
		return staticMenuImplBo;
	}

	@Bean
	public static MenuImpl createStaticMenuImplBo(){
		return new MenuImpl();
	}
}

实现接口的处理器

public class TestImportSelector implements ImportSelector {
   @Override
   public String[] selectImports(AnnotationMetadata importingClassMetadata) {
      return new String[]{ServiceBo.class.getName()};
   }
}
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
   @Override
   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
      System.out.println("TestBeanDefinitionRegistryPostProcessor---->postProcessBeanDefinitionRegistry");
   }

   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("TestBeanDefinitionRegistryPostProcessor---->postProcessBeanFactory");
   }
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("TestBeanFactoryPostProcessor---->postProcessBeanFactory");
   }
}

自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Import(TestImportSelector.class)
public @interface ImportSelectorAnno {
}
@Retention(RetentionPolicy.RUNTIME)
@Import(TestBeanFactoryPostProcessor.class)
public @interface BeanFactoryPostProcessorAnno {
}
@Retention(RetentionPolicy.RUNTIME)
@Import(TestBeanDefinitionRegistryPostProcessor.class)
public @interface BeanDefinitionRegistryPostProcessorAnno {
}

上面的内容有一段是初始化DefaultListableBeanFactory 工厂之后实例化一个注解读取器,我们点进去看看实例化还做了什么

this.reader = new AnnotatedBeanDefinitionReader(this);

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#

AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry)

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#

AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.core.env.Environment)

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

org.springframework.context.annotation.AnnotationConfigUtils#

registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)

org.springframework.context.annotation.AnnotationConfigUtils#

registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   if (beanFactory != null) {}
   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition();
      def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
               AnnotationConfigUtils.class.getClassLoader()));
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
   }

   return beanDefs;
}

通过上面的方法我们看到了

第一个对象 BeanDefinitionHolder(由于BeanDefinition 没有beanName 属性,所以spring内部封装的一个对象用来存 beanName 和 BeanDefinition)

第二个对象 RootBeanDefinition 内部 自己 root 为一个BeanDefinition 然后再将这个 BeanDefinition 注册到spring容器中

有几个呢

ConfigurationClassPostProcessor.class 就是上面提到的一个后置处理器(为什么第一个是它呢?因为扫描解析(执行BeanPostProcessor后置处理器)的时候就需要用到比如@Configuration注解,@Bean注解等等....)

org.springframework.context.support.AbstractApplicationContext#

invokeBeanFactoryPostProcessors

org.springframework.context.support.PostProcessorRegistrationDelegate#

invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)

这一步代码执行完成后就完成了spring的扫描解析和BeanDefinition的初始化即BeanDefinitionMap填充

AutowiredAnnotationBeanPostProcessor.class 可以理解为解析 @Autowired 注解

CommonAnnotationBeanPostProcessor.class 解析 @Resource 注解

等等......还有我们刚刚自定义的

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
this();//进行读取和扫描,实例化benaFactory工厂,实例化内部benaFactory后置处理器
register(annotatedClasses);//注册配置类
refresh()#prepareBeanFactory(beanFactory);//完善beanFactory工厂属性
refresh()#invokeBeanFactoryPostProcessors(beanFactory);//执行内部benaFactory后置处理器及自定义benaFactory后置处理器

 org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
   Set<BeanDefinition> candidates = new LinkedHashSet<>();
   try {
      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;
      Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
      boolean traceEnabled = logger.isTraceEnabled();
      boolean debugEnabled = logger.isDebugEnabled();
      for (Resource resource : resources) {
         if (traceEnabled) {
            logger.trace("Scanning " + resource);
         }
         if (resource.isReadable()) {
            try {
               MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
               if (isCandidateComponent(metadataReader)) {
                  ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                  sbd.setResource(resource);
                  sbd.setSource(resource);
                  if (isCandidateComponent(sbd)) {
                     if (debugEnabled) {
                        logger.debug("Identified candidate component class: " + resource);
                     }
                     candidates.add(sbd);
                  }
                  
  //删除了部分
   }
   
   return candidates;
}

register(annotatedClasses);-->@Configuration:AnnotatedGenericBeanDefinition

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {


   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

   /**
    *  判断这个类是否需要跳过解析
    *  通过代码可以知道 spring 判断是否跳过解析 主要判断类有没有加注解
    */
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
   }

   abd.setInstanceSupplier(instanceSupplier);


   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

   abd.setScope(scopeMetadata.getScopeName());

   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

   if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   //自定义注解
   for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
   }

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

   // 数据结构 beanDefinition = definitionHolder.getBeanDefinition();
   // beanDefinitionMap.put(beanName, beanDefinition);
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

其它的就不一一看呢,后面讲的会涉及到的也会列举出来,具体解析在这个方法中

org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass

我们接下来看看这个方法refresh()#invokeBeanFactoryPostProcessors(beanFactory);

bean工厂后置处理器的调用时机和顺序,也顺便看看spring的设计思想

下面是这个方法的代码,我会用上面的测试代码的环境进行阅读,方法有点长,一起来看看

 public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // 如果有的话,先调用BeanDefinitionRegistryPostProcessors
    Set<String> processedBeans = new HashSet<>();
    // (beanFactory == DefaultListableBeanFactory) instanceof BeanDefinitionRegistry == true
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        // 从入口的调用链看过来 BeanFactoryPostProcessor 默认传的为空
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // 准备执行当前的 BeanDefinitionRegistryPostProcessor 后置处理器
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        //  优先执行这一个(有且仅有一个) 系统创建的 ConfigurationClassPostProcessor
        //  可以理解为执行系统的
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 将系统创建的 ConfigurationClassPostProcessor 放到当前执行的后置处理器集合中
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);// 此集合的作用为判断该后置处理器是否已经执行过了
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 这句代码是这个方法的关键 去执行 ConfigurationClassPostProcessor(子类) 里面重写的方法和解析注解
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();//执行完该处理器后清空

        // ConfigurationClassPostProcessor
        // TestBeanDefinitionRegistryPostProcessor
        // 可以理解为执行自定义的 但是未实现 Ordered 接口 所以当前环境也不会进
        postProcessorNames = 
        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            // !processedBeans.contains(ppName) --> ConfigurationClassPostProcessor == false
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(
                beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 最后,调用所有其他的beandefinitionregistrypostprocessor,直到没有其他的出现。
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            //获取到上面的那两个
            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();
        }

        // 现在,调用到目前为止处理的所有处理器的postProcessBeanFactory(父类)回调
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // 调用用上下文实例注册的工厂处理器。
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    //=======下面的代码对于 ConfigurationClassPostProcessor 来说都不关键 =========
    // 获取所有实现了 BeanFactoryPostProcessor 的后置处理器 加上内置的和自定义的当前环境中一共有四个
    // ConfigurationClassPostProcessor(已执行过) TestBeanDefinitionRegistryPostProcessor(已执行过)
    // internalEventListenerProcessor TestBeanFactoryPostProcessor
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    //将实现priorityor的beanfactorypostprocessor分开,
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    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);
        }
    }

    // 首先,调用实现priorityor的beanfactorypostprocessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 接下来,调用实现Ordered的beanfactorypostprocessor。
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    //最后,调用所有其他beanfactorypostprocessor
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    //清除缓存的合并bean定义,因为后处理器可能有
    //修改了原始的元数据,例如替换了值中的占位符…
    beanFactory.clearMetadataCache();
}

执行顺序是先执行系统内置的子类处理器方法,在执行自定义的处理器方法(有一个顺序有没有实现 order 接口,如果有看实现该接口重写的getOrder方法返回的值做比较后顺序执行,最后在执行父类处理器的方法)---策略者模式
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);执行父类的方法主要之一是做cglib代理

会设置这两个属性

isFullConfigurationClass -->CONFIGURATION_CLASS_FULL

isLiteConfigurationClass -->CONFIGURATION_CLASS_LITE

关于这两个属性的区别

我们先着重看一看invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);做了什么

去执行 ConfigurationClassPostProcessor 里面重写的方法(包括解析注解)到这里真正意义上的扫描工作并未完成

进去这个方法之后就跟踪到了这个方法ConfigurationClassPostProcessor#processConfigBeanDefinitions

 明日更新12月1号上午完成

执行完成之后我们容器大概的模型就是现在这个样子

猜你喜欢

转载自blog.csdn.net/qq_38108719/article/details/103318189