Springboot Analysis (3) - Container Refresh Process

First, first understand the various post-processor extension points

(1) BeanFactoryPostProcessor - bean factory post-processing

After the BeanFactory standard is initialized (all BeanDefinitions have been registered after the package scan), the BeanFactory can be post-processed.

(2) BeanDefinitionRegistryPostProcessor - bean definition registry post processing

The sub-interface of BeanFactoryPostProcessor has an additional postProcessBeanDefinitionRegistry method, which allows post-processing of the BeanDefinitionRegistry (bean definition registry) before the bean is instantiated.

(3) BeanPostProcessor - bean post processor

Provides extension points for post-processing of instantiated beans. Typically used to reprocess beans that will be instantiated into the container.

(4) MergedBeanDefinitionPostProcessor - Merged Bean Definition Post Processor

A sub-interface of BeanPostProcessor, with one more postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)method for post-processing merged bean definitions.

2. Container refresh process

(1) Main code

//最终调到AbstractApplicationContext的refresh方法
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 初始化前的预处理,初始化Environment里面的PropertySources(猜测是webXML里面的东西),debug下没有什么用
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        //  获取BeanFactory,直接返回的是前面初始化的beanFactory,只不过设置了一下SerializationId
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 3. BeanFactory的预处理配置
	//(1) 在容器注册了ApplicationContextAwareProcessor这个Bean后置处理器用于处理实现了XXXAware接口的bean,调用其setXXX方法。
	//(2)忽略一些自动注入,以及添加一些自动注入的支持,为什么要忽略这些自动注入勒,因为当beanDefinition的AutowireMode为1(按setXXX方法的名称进行注入)和2(按setXXX方法返回值类型进行自动注入)时,若自动注入生效,该Bean的setXXX方法将被自动注入,那么为了避免和XXXAware接口冲突,所以进行了忽略。
	//(3) 添加一些自动注入支持,包含BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext。
	//(4) 在容器注册了new ApplicationListenerDetector(this)这个Bean后置处理器用于收集所有实现了ApplicationListener接口的bean并收集到容器中的一个集合中。
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 4. 准备BeanFactory完成后进行的后置处理
	    //以servlet环境为例:
	    //(1) 添加了一个bean的后置处理器处理ServletContextAware和ServletConfigAware,用于注入ServletContext和ServletConfig。
	    //(2) 往容器注册Scope,Scope描述的是Spring容器如何新建Bean实例的,这里注册了Request以及Session两个Scope并且注册ServletRequest、ServletResponse、HttpSession、WebRequest为自动装配。
	    //(3)当判断容器的basePackages属性不为null的时候进行包扫描(但debug下这里没执行)。
	    //(4)当判断容器的annotatedClasses属性不为null也进行注册(debug下没执行)。
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 5. 执行BeanFactory创建后的后置处理器,
			// 这一步里面会处理ConfigurationClassPostProcessor这个bd后置处理器完成所有的bd注册
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 6. 注册Bean的后置处理器
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7. 初始化MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            // 8. 初始化事件派发器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 9. 子类的多态onRefresh,比如在 ServletWebServerApplicationContext.onRefresh方法中启动了web容器
            onRefresh();

            // Check for listener beans and register them.
            // 10. 注册监听器
            registerListeners();
            //到此为止,BeanFactory已创建完成
            // Instantiate all remaining (non-lazy-init) singletons.
            // 11. 初始化所有剩下的单例Bean
            finishBeanFactoryInitialization(beanFactory);
            // Last step: publish corresponding event.
            // 12. 完成容器的创建工作
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
            // Reset 'active' flag.
            cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            // 13. 清除缓存
            resetCommonCaches();
        }
    }
}

(2) Core point

1.prepareBeanFactory(beanFactory)-BeanFactory preprocessing configuration

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   // 设置BeanFactory的类加载器、表达式解析器等
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   //  配置一个BeanPostProcessor,这个Bean后处理器将实现了以下几个Aware的bean分别回调对应的方法
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	// 配置ignoreDependencyInterface,是的这些类型自动装配无效,但实测@Autowired注入时还是能装配,故这里的意思是为了避免其他bd设置了自动注入,即AutowireMode,而不是指使用@Autowired注解进行的依赖注入。
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
   // 自动注入的支持
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   // 配置一个可加载所有监听器的组件
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
       beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
       // Set a temporary ClassLoader for type matching.
       beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
   // 注册了默认的运行时环境、系统配置属性、系统环境的信息
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
       beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
       beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
       beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

There are four main things here:

  1. The Bean post-processor, ApplicationContextAwareProcessor, is registered in the container to process beans that implement the XXXAware interface and call its setXXX method.
  2. Ignore some automatic injections, and add some automatic injection support, why ignore these automatic injections, because when the AutowireMode of the beanDefinition is 1 (injection by the name of the setXXX method) and 2 (automatic injection by the return value type of the setXXX method) When the automatic injection takes effect, the setXXX method of the bean will be automatically injected, so in order to avoid conflict with the XXXAware interface, it is ignored.
  3. Add some automatic injection support, including BeanFactory, ResourceLoader, ApplicationEventPublisher, ApplicationContext.
  4. The new ApplicationListenerDetector(this) Bean post-processor is registered in the container to collect all beans that implement the ApplicationListener interface and collect them into a collection in the container.

2. postProcessBeanFactory(beanFactory)-prepare the post-processing after the BeanFactory is completed

Take a servlet as an example: the ApplicationContext implementation here is actually AnnotationConfigServletWebServerApplicationContext. In the AnnotationConfigServletWebServerApplicationContext class, this method is mainly completed:

  1. A post-processor that registers a bean with the container handles ServletContextAware and ServletConfigAware for injecting ServletContext and ServletConfig.
  2. Register Scope with the container. Scope describes how the Spring container creates a new Bean instance. Here, two Scopes, Request and Session, are registered, and ServletRequest, ServletResponse, HttpSession, and WebRequest are registered for automatic assembly.
  3. When it is judged that the basePackages property of the container is not null, package scanning is performed (but it is not executed here under debug).
  4. When it is judged that the annotatedClasses property of the container is not null, it is also registered (not executed under debug).

3.invokeBeanFactoryPostProcessors(beanFactory)-executes the post-processors created by the BeanFactory

Code:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 执行BeanFactory后置处理器
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

进入 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()):

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

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    //用于存放已经执行了的processedBeans
    Set<String> processedBeans = new HashSet<>();

    // 这里要判断BeanFactory的类型,默认SpringBoot创建的BeanFactory是DefaultListableBeanFactory
    // 这个类实现了BeanDefinitionRegistry接口,则此if结构必进
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
		//遍历已经注册到beanFactory的BeanFactoryPostProcessor后置处理器,然后分类为regularPostProcessors和registryProcessors
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                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.
     	//这个currentRegistryProcessors变量用于分阶段执行方法,因为有PriorityOrdered和Ordered接口的存在
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
  
        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        // 首先,调用实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors并添加到processedBeans
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
		//排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        //添加到registryProcessors
        registryProcessors.addAll(currentRegistryProcessors);
        //执行
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        // 接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
		//排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        //添加到registryProcessors
		registryProcessors.addAll(currentRegistryProcessors);
		//执行
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        // 最后,调用所有其他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();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        // 回调所有BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        // 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
        // 再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
    }

    // 如果BeanFactory没有实现BeanDefinitionRegistry接口,则进入下面的代码流程
    else {
        // Invoke factory processors registered with the context instance.
        // 调用在上下文实例中注册的工厂处理器。
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 下面的部分是回调BeanFactoryPostProcessor,思路与上面的几乎一样
  
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    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);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    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.
    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();
}

The above code is a bit long and the main things to do are:

  1. The first step is to obtain the beanFactoryPostProcessors of the beanFactoryPostProcessor that has been registered in the container (different from beanDifinitionMap, where the variable beanFactoryPostProcessors in the container is used instead of obtained from the beanDefinition), and filter those that implement the BeanDefinitionRegistryPostProcessor interface, and execute its postProcessBeanDefinitionRegistry method.
  2. The second step is to obtain the beans of type BeanDefinitionRegistryPostProcessor in the registered beanDefinition in the container, filter the beans that implement the PriorityOrdered interface, sort them, and then call back their postProcessBeanDefinitionRegistry. The most important ConfigurationClassPostProcessor is executed here, which will process the configuration annotations in the current beandifinitonMap, such as processing @Component , @ComponentScan , @Import , @ImportResource , @PropertySource , @ComponentScan , @Import , @ImportResource , @Bean Annotate, register all beanDefinitions, and expand on this ConfigurationClassPostProcessor later.
  3. The third step is to obtain the beans of type BeanDefinitionRegistryPostProcessor in the registered beanDefinition in the container, and they will be sorted according to whether they implement the PriorityOrdered interface or the Ordered interface (the general order is PriorityOrdered priority Ordered priority does not implement the interface, the same interface is determined by the return value of the method), Then call its postProcessBeanDefinitionRegistry method.
  4. The fourth step is to execute the postBeanFactory method of all beans of type beanDefinitionRegistryPostProcessor above.
  5. The fifth step is to call the postBeanFactory method of the beanFactoryPostProcessor in the ApplicationContext (different from beanDifinitionMap, where the variable beanFactoryPostProcessors is used instead of beanDefinition), which does not belong to the BeanDefinitionRegistryPostProcessor interface (that is, just BeanFactoryProcessor).
  6. The sixth step calls the postBeanFactory method of all other BeanFactoryPostProcessors, and also parses the PriorityOrdered and Ordered interfaces.

Next, we will focus on the source code of ConfigurationClassPostProcessor executed in the second step. The internal details will not be expanded. The approximate process has been written in the comments:

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);
    processConfigBeanDefinitions(registry);
}

The meaning here is to get the container ID, get whether it has been called, and if not, continue to execute processConfigBeanDefinitions. Take a look at the processConfigBeanDefinitions(registry) method:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();

    // 确定配置类和组件
	//带有@Configuration注解的bd的configurationClass值设为full,
	//带有@Component 、@ComponentScan 、@Import 、@ImportResource注解或方法中添加了带@Bean的方法
	//(只是将带bean的方法收集起来,并没有注册bd)的设为configurationClass值设为lite,并加入到configCandidates
    for (String beanName : candidateNames) {
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }

    // Return immediately if no @Configuration classes were found
    if (configCandidates.isEmpty()) {
        return;
    }

    // Sort by previously determined @Order value, if applicable
    // 对配置类进行排序
    configCandidates.sort((bd1, bd2) -> {
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return Integer.compare(i1, i2);
    });

    // Detect any custom bean name generation strategy supplied through the enclosing application context
    // 加载获取BeanNameGenerator
    SingletonBeanRegistry sbr = null;
    if (registry instanceof SingletonBeanRegistry) {
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }

    if (this.environment == null) {
        this.environment = new StandardEnvironment();
    }

    // Parse each @Configuration class
    // 初始化配置类解析器
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);
	//需要解析的配置类集合
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    //已经解析的配置类集合
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        // 解析配置类,最重要的方法
		//对configCandidates按照@Order进行排序并遍历进行递归一直解析父类,
		//需解析@PropertySource 、@ComponentScan 、@Import 、@ImportResource 、@Bean注解(注这一步还没有对扫描到的组件完全进行Bd注册,
		//而只是注册了包扫描到的bd以及处理@Import注解时实现了ImportBeanDefinitionRegistrar或者ImportSelector接口的bd,
		//并且这里会先处理一个类的嵌套配置类)
        parser.parse(candidates);
		//校验
        parser.validate();
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // Read the model and create bean definitions based on its content
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        //解析配置类中的内容
		//将通过@Import、@Bean注解方式注册的类以及处理@ImportResource注解引入的配置文件解析成BeanDefinition,然后注册到BeanDefinitionMap中。
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);
        candidates.clear();
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
		   //当前的bdNames
            String[] newCandidateNames = registry.getBeanDefinitionNames();
			//上一次解析之前的bdNames
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			//这次解析的bdNames
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
			//遍历当前bdNames,若不是以前有的,并且是配置类,并且没有被解析到,则添加到candidates,下一次循环再解析一次
            for (String candidateName : newCandidateNames) {
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());

    // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    // 将ImportRegistry注册为Bean,以支持ImportAware 和@Configuration类
    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    }

    // 清除缓存
    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        // Clear cache in externally provided MetadataReaderFactory; this is a no-op
        // for a shared cache since it'll be cleared by the ApplicationContext.
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}

4.registerBeanPostProcessors(beanFactory)-registers bean post processors (including MergedBeanDefinitionPostProcessor)

The registration logic is similar to the registration of beanFactoryPostProcessor. The registration order will determine the priorityOrdered and Ordered interfaces, and first register the MergedBeanDefinitionPostProcessor and then register the beanFactoryPostProcessor.

There are two MergedBeanDefinitionPostProcessor, one is AutowiredAnnotationBeanPostProcessor, one is ApplicationListenerDetector.

  • AutowiredAnnotationBeanPostProcessor will parse the bean's auto-injection properties, determine whether there are any dependencies, and register dependencies through registerExternallyManagedConfigMember.
  • ApplicationListenerDetector functions to collect a map with beanName as the key and singleton as the value.

5. initMessageSource() - Initialize MessageSource

messageSource is mainly an international component provided by spring, and the corresponding yml configuration is:

spring: 
  messages:
    basename: i18n/messages
    encoding: UTF-8

In this way, the getMessage method of messageSource can find the corresponding messageXXX.properties file in the i18n directory, compare it with the Locale in the parameter, and return the corresponding internationalized message.

The methods in messageSource are:

//有默认值返回
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
//无默认值,找不到抛异常
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
//MessageSourceResolvable封装了code,args,defaultMessage
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

Parameter explanation:

  • The key of code information, the key in properties,
  • args, used for template replacement of parameters in message.
  • locale country
  • MessageSourceResolvable encapsulates code, args, defaultMessage, and the code parameter is in the form of String[] array. The information is obtained by traversing the call. As long as one of the codes can obtain the value, it will return directly. When no data is queried and the defaultMessage is empty, a NoSuchMessageException is thrown directly.

The source code here will check whether there is a messageSource in bd. If not, the default messageSource and DelegatingMessageSource classes will be initialized directly.

6. initApplicationEventMulticaster() - initializes the event broadcaster

This is also to scan whether there is applicationEventMulticaster in bd. If not, use the default SimpleApplicationEventMulticaster. It should be noted here that before this, there are actually event distributions during the springboot startup process. For example, the start method of SpringApplicationRunListener is called when the container starts. , how does it do le? Actually it uses the internal SimpleApplicationEventMulticaster to complete the event broadcasting. And here and the listener to be registered later is not the same event broadcaster used.

7.onRefresh

Different web containers will implement polymorphism, such as ServletWebServerApplicationContext will create embedded servlet container.

8.registerListeners() - register listeners

Register listeners and broadcast early events (just an extension point for springboot itself, this extension point allows to broadcast some early events when post-processors and listeners are created, and the rest of the single-instance beans have not yet been created ), through debug to see that there is currently no early events deposited.

9.finishBeanFactoryInitialization(beanFactory)-initialize a singleton bean

Compare the core, initialize other singleton beans, and solve circular dependencies.

10.finishRefresh()

Clear resource caches (such as scanned ASM metadata), process lifecycle handlers (Lifecycle interface), and publish container refresh completion events. ServletWebServerApplicationContext will call the start method of WebServer at the end.

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324038698&siteId=291194637