Spring源碼9. refreshContext()刷新應用上下文

上篇回顧

上一篇prepareContext()準備應用上下文中分析了spring容器的準備, 共計執行了如下8步:

  1. 統一了ApplicationContext和Application的environment
  2. 設置ApplicationContext的beanNameGenerator,resouceLoader和classLoader, 并設置beanFactory的類型轉換Service
  3. 執行Initializer
  4. 發布ApplicationContextInitializedEvent
  5. 打印啟動日志和profile日志
  6. 手工注冊命令行和banner兩個單例Bean
  7. 初始化BeanDefinitionLoader, 加載啟動類sources
  8. 發布contextLoaded事件

目錄

1. 刷新應用上下文

2. AbstractApplicationContext#refresh

3. 準備刷新 prepareRefresh()

????3.1 AnnotationConfigServletWebServerApplicationContext
????3.2 AbstractApplicationContext

4. 獲取并刷新beanFactory

5. 準備beanFactory

6. beanFactory的后置處理器

7. 實現beanFactory的后置處理器

8.注冊bean處理器

9.國際化 initMessageSource()

10. 注冊事件發布器

11. 通知子類刷新刷新容器 onRefresh()

????ServletWebServerApplicationContext
????GenericWebApplicationContext

12.注冊監聽器 registerListeners()

13. 完成beanFactory初始化, 實例化所有非延遲加載的bean

14.完成刷新 finishRefresh() 發布ContextRefreshedEvent

15. 異常處理

16. 清除緩存 resetCommonCaches()


1. 刷新應用上下文

public class SpringApplication {
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            
            //本文的重點
            //刷新應用上下文
            refreshContext(context);
        //...
    }
    
    //刷新應用上下文,注冊關閉應用鉤子
    private void refreshContext(ConfigurableApplicationContext context) {
        
        refresh(context);
        if (this.registerShutdownHook) {
            //registerShutdownHook默認為true
            try {
                //注冊shutdown方法
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) { }
        }
    }
    
    //刷新應用上下文
    //調用AbstractApplicationContext#refresh方法
    protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext) applicationContext).refresh();
    }
}

2. AbstractApplicationContext#refresh

/**
 * 抽象父類ApplicationContext
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //準備刷新
            prepareRefresh();
            
            //刷新beanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //準備beanFactory
            prepareBeanFactory(beanFactory);

            try {
                //beanFactory的后置處理器
                postProcessBeanFactory(beanFactory);

                //實現beanFactory的后置處理器
                invokeBeanFactoryPostProcessors(beanFactory);

                //beanFactory注冊后置處理器
                registerBeanPostProcessors(beanFactory);

                //初始化messageSource
                initMessageSource();

                //初始化Application事件發布器
                initApplicationEventMulticaster();

                //初始化其他特殊的bean
                onRefresh();

                //注冊監聽器
                registerListeners();

                //完成beanFactory初始化
                finishBeanFactoryInitialization(beanFactory);

                //完成刷新,發布完成事件
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    //打印告警日志
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
                //捕獲到異常,銷毀已經注冊的bean
                destroyBeans();
                
                //捕獲到異常,取消刷新
                cancelRefresh(ex);
                
                //拋出異常
                throw ex;
            }

            finally {
                //重置緩存
                resetCommonCaches();
            }
        }
    }
}

3. 準備刷新 prepareRefresh()

準備刷新, 執行了兩步:

  1. 調用當前類AnnotationConfigServletWebServerApplicationContext的prepareRefresh()方法
  2. 顯式調用super.prepareRefresh()方法,也就是AbstractApplicationContext的prepareRefresh方法
3.1 AnnotationConfigServletWebServerApplicationContext#prepareRefresh

清空CachingMetadataReaderFactory中的緩存

public class AnnotationConfigServletWebServerApplicationContext
        extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
    //準備刷新
    @Override
    protected void prepareRefresh() {
        //如果類掃描器中的metadataReaderFactoryy是CachingMetadataReaderFactory的子類
        //那么清除類掃描器中beanFactory維護的所有的bean
        this.scanner.clearCache();
        //顯式調用父類AbstractApplicationContext的prepareRefresh方法
        super.prepareRefresh();
    }
}

3.2 AbstractApplicationContext#prepareRefresh

設置刷新開始事件, 設置closed為false, active為true, 標記容器處于active狀態

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    //準備刷新
    protected void prepareRefresh() {
        //記錄開始時間,調整active狀態
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        if (logger.isDebugEnabled()) {
            //打印debug日志
            if (logger.isTraceEnabled()) {
                logger.trace("Refreshing " + this);
            }
            else {
                logger.debug("Refreshing " + getDisplayName());
            }
        }

        //初始化占位符,例如:$,#,{}
        //GenericWebApplicationContext#initPropertySources
        initPropertySources();

        //當前environment為StandardServletEnvironment
        //調用AbstractEnvironment#validateRequiredProperties()方法
        //然后調用AbstractPropertyResolver#validateRequiredProperties()方法
        //如果屬性中缺少requiredProperties
        //那么拋出MissingRequiredPropertiesException
        getEnvironment().validateRequiredProperties();

        if (this.earlyApplicationListeners == null) {
            //如果earlyApplicationListeners為null
            //保存applicationListeners
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            //如果earlyApplicationListeners不為null
            //將earlyApplicationListeners同步到applicationListeners中
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        //初始化earlyApplicationEvents
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }
}

4. 獲取并刷新beanFactory

AbstractApplicationContext中定義了模板方法, refreshBeanFactory和getBeanFactory調用的是GenericApplicationContext中實現的方法

public abstract class AbstractApplicationContext extends DefaultResourceLoader{

    //id獲取
    private String id = ObjectUtils.identityToString(this);

    
    //刷新并返回beanFactory
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        return getBeanFactory();
    }
    
    @Override
    public String getId() {
        return this.id;
    }
}
GenericApplicationContext#refreshBeanFactory

更新this.refreshed字段為true, 表示已經更新了, 然后beanFactory設置serializationId, 最后返回beanFactory

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    //內部的beanFactory
    private final DefaultListableBeanFactory beanFactory;
    //原子bool值
    private final AtomicBoolean refreshed = new AtomicBoolean();
    
    //刷新beanFactory
    @Override
    protected final void refreshBeanFactory() throws IllegalStateException {
        //原子自旋, 更新refreshed為true
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException(
                    "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        }
        //調用AbstractApplicationContext的getId()方法
        this.beanFactory.setSerializationId(getId());
    }
    
    //返回beanFactory
    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }
}

5. 準備beanFactory

beanFactory是GenericApplicationContext中DefaultListableBeanFactory類型的成員變量, 設置beanFactory, 一共執行了

  • 配置classLoader為當前context的classLoader
  • 設置BeanExpressionResolver, 解析EL表達式
  • 設置屬性編輯器
  • 添加BeanPostProcessor
  • 配置自動裝配
  • 手工注冊environment相關bean
public abstract class AbstractApplicationContext extends DefaultResourceLoader{
    protected void  prepareBeanFactory()(ConfigurableListableBeanFactory beanFactory) {
        //beanFactory設置為當前context的classLoader
        beanFactory.setBeanClassLoader(getClassLoader());
        //beanFactory設置BeanExpressionResolver,解析EL表達式
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //beanFactory配置屬性編輯器,也就是類型轉換器
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        //ApplicationContextAwareProcessor會在加載Aware接口的時候, 傳遞參數到相應的Aware實現類中
        //所以需要忽略Aware接口的自動裝配
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //配置忽略自動裝配
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

        // 配置自動裝配規則, 例如@Autowired注解注入
        // 如果需要BeanFactory,那么注入beanFactory
        // 如果需要ResourceLoader,ApplicationEventPublisher,ApplicationContext,則注入this
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        //添加ApplicationListenerDetector的beanPostProcessor
        //ApplicationListenerDetector會檢測實現了ApplicationListener接口的bean
        //在這些bean在實例化的過程中,記錄到singletonNames 中
        //在bean被銷毀的時候, 從applicationContext的applicationEventMulticaster中移除
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        //添加LoadTimeWeaverAwareProcessor
        //解析@EnableLoadTimeWeaving注解
        //在類加載到JVM中時, 織入切面
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            //添加bean處理器,實現對AspectJ的支持
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            //設置classloader
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // 手工注冊environment的相關bean
        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());
        }
    }
}

6. beanFactory的后置處理器 postProcessBeanFactory(beanFactory)

后續處理各個beanFactory, 當前applicationContext是AnnotationConfigServletWebServerApplicationContext的實例, postProcessBeanFactory執行了三步

  • 調用了父類方法
  • 判斷basePackages是否為空, 不為空的話, 掃描this.basePackages
  • 判斷annotatedClasses是否為空, 不為空的話, 注冊bean
AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory
public class AnnotationConfigServletWebServerApplicationContext
        extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
    //處理beanFactory
    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //顯式調用父類ServletWebServerApplicationContext#postProcessBeanFactory
        super.postProcessBeanFactory(beanFactory);
        //basePackages默認為null
        if (this.basePackages != null && this.basePackages.length > 0) {
            //不為空的話,進行掃描
            this.scanner.scan(this.basePackages);
        }
        //annotatedClasses默認為空
        if (!this.annotatedClasses.isEmpty()) {
            //不為空的話注冊類
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }
    }

}
ServletWebServerApplicationContext#postProcessBeanFactory

進行了兩個操作, 首先添加了一個WebApplicationContextServletContextAwareProcessor的Aware Bean處理器, ServletContextAware的子類Bean在實例化過程中, 會被注入servletContext和servletConfig對象, 然后beanFactory中注冊了request和session兩個scopes, 注冊了幾個Autowired依賴類

public class ServletWebServerApplicationContext extends GenericWebApplicationContext
        implements ConfigurableWebServerApplicationContext {
    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //在ServletContext和ServletConfig初始化之前
        //進行bean處理
        beanFactory.addBeanPostProcessor(
                new WebApplicationContextServletContextAwareProcessor(this));
        //忽略ServletContextAware自動配置
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        //beanFactory注冊web應用scopes
        //request和session
        registerWebApplicationScopes();
    }
}
WebApplicationContextUtils#registerWebApplicationScopes

注冊了request, session兩個scope, 然后注冊ServletRequest, ServletResponse, HttpSession, WebRequest

public abstract class WebApplicationContextUtils# {


    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
        //傳入ServletContext為null
        registerWebApplicationScopes(beanFactory, null);
    }

    
    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
            @Nullable ServletContext sc) {

        //注冊Scope
        //request
        beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
        //session
        beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
        if (sc != null) {
            //傳入sc為null
            //注冊application scope
            ServletContextScope appScope = new ServletContextScope(sc);
            beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
            // 設置ServletContext屬性
            sc.setAttribute(ServletContextScope.class.getName(), appScope);
        }

        //注冊幾個Autowired自動裝配
        //ServletRequest.class
        beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
        //ServletResponse.class
        beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
        //HttpSession.class
        beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
        //WebRequest.class
        beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
        if (jsfPresent) {
            //jsfPresent默認為false
            FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
        }
    }
}

7. 實現beanFactory的后置處理器

BeanFactoryPostProcessor是一個接口, 處理beanFactory中所有的bean, 在所有的beanDefinition加載完成之后, BeanFactoryPostProcessor可以對beanDefinition進行屬性的修改, 之后再進行bean實例化

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口, 定義了postProcessBeanDefinitionRegistry方法, 會在postProcessBeanFactory方法執行之前, 獲取bean定義, 并注冊到spring容器中

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    //處理器代理類
    //處理this.beanFactoryPostProcessors中維護的bean處理器
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    //TempClassLoader為空
    //包含了LoadTimeWeaver(加載到JVM時, 進行切面織入)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}
7.1 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

如果beanFactory是BeanDefinitionRegistry的子類, 按優先級處理BeanDefinitionRegistryPostProcessor類型的后置處理器, 最后處理傳入的其他類型后置處理器, 處理流程如下:

首先處理傳入的beanFactoryPostProcessors, 將傳入的beanFactoryPostProcessors分為兩個部分

  1. BeanDefinitionRegistryPostProcessor子類, 執行其postProcessBeanDefinitionRegistry方法, 然后維護到registryProcessors的列表中
  2. 非BeanDefinitionRegistryPostProcessor子類, 維護到regularPostProcessors列表中

然后處理beanFactory中注冊的BeanDefinitionRegistryPostProcessor類型的bean

  1. 優先處理實現了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor, 一共分為5個步驟
  • 生成bean, 維護到currentRegistryProcessors列表中
  • processedBeans中添加bean名稱, 標記已經被處理
  • currentRegistryProcessors列表排序, 并添加到registryProcessors中
  • 遍歷registryProcessors列表, 調用每個元素的postProcessBeanDefinitionRegistry方法
  • 然后清空currentRegistryProcessors
  1. 然后處理實現了Ordered接口的BeanDefinitionRegistryPostProcessor, 一共分為5個步驟
  • 先判斷processedBeans中是否包含了beanName, 如果包含了就不處理
  • 生成bean, 維護到currentRegistryProcessors列表中
  • processedBeans中添加bean名稱, 標記已經被處理
  • currentRegistryProcessors列表排序, 并添加到registryProcessors中
  • 遍歷registryProcessors列表, 調用每個元素的postProcessBeanDefinitionRegistry方法
  • 然后清空currentRegistryProcessors
  1. 處理剩下的所有BeanDefinitionRegistryPostProcessor, 方法同第2步
  2. 遍歷registryProcessors, 調用其postProcessBeanFactory方法
  3. 遍歷所有的regularPostProcessors, 調用其postProcessBeanFactory方法

如果beanFactory不是BeanDefinitionRegistry的子類, 那么直接遍歷傳入的傳入的beanFactoryPostProcessors, 調用元素的postProcessBeanFactory方法

最后處理beanFactory中注冊的其他類型的BeanFactoryPostProcessor, 獲取bean名稱, 維護到postProcessorNames列表中, 之后的處理步驟如下:

  1. 首先處理實現了PriorityOrdered接口的BeanFactoryPostProcessor
  • 獲取bean, 維護到priorityOrderedPostProcessors列表中
  • priorityOrderedPostProcessors排序
  • 遍歷priorityOrderedPostProcessors, 執行其postProcessBeanFactory方法
  1. 然后處理實現了Ordered接口的BeanFactoryPostProcessor, 方法同上
  1. 最后處理其他BeanFactoryPostProcessor, 方法同上

ConfigurationClassPostProcessor處理了@Configuration注解, 掃描項目中的BeanDefinition, 這篇文章 詳細剖析了ConfigurationClassPostProcessor的源碼

final class PostProcessorRegistrationDelegate {
    /**
     * @param beanFactory 
     * @param beanFactoryPostProcessors有三個:
     *      CachingMetadataReaderFactoryPostProcessor
     *      ConfigurationWarningsPostProcessor
     *      PropertySourceOrderingPostProcessor
     */
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        //processedBeans記錄處理過的bean名稱
        Set<String> processedBeans = new HashSet<>();
        
        if (beanFactory instanceof BeanDefinitionRegistry) {
            //優先處理傳入的BeanDefinitionRegistryPostProcessor
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            //非BeanDefinitionRegistryPostProcessor類型, 常規BeanFactory后置處理器
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            //BeanDefinitionRegistryPostProcessor類型的bean定義注冊器后置處理器
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
            //regularPostProcessors有1個:PropertySourceOrderingPostProcessor
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    //bean定義注冊器后置處理器,有如下兩個:
                    //CachingMetadataReaderFactoryPostProcessor
                    //ConfigurationWarningsPostProcessor
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                            //執行其postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    //然后加入到registryProcessors中
                    registryProcessors.add(registryProcessor);
                }
                else {
                    //如果不是BeanDefinitionRegistryPostProcessor
                    //那么放入regularPostProcessors(常規后置處理器)中
                    regularPostProcessors.add(postProcessor);
                }
            }

            //處理beanFactory中注冊的BeanDefinitionRegistryPostProcessor
            
            //當前正在處理的PostProcessor, 處理完成之后會清空
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            //將其名稱放入postProcessorNames數組中
            //當前只能獲取到一個bean:        
            //名稱為org.springframework.context.annotation.internalConfigurationAnnotationProcessor
            //類型為ConfigurationClassPostProcessor
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    //優先處理PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //處理完成之后, 放到processedBeans列表
                    processedBeans列表中.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //添加到registryProcessors
            registryProcessors.addAll(currentRegistryProcessors);
            //遍歷currentRegistryProcessors,調用其postProcessBeanDefinitionRegistry方法
            //執行ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry, 掃描并注冊模塊中@Configuration注解的bean
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            //清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // 實現Order注解的bean
            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.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);
                //調用其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            //調用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            //方法傳入普通BeanFactoryPostProcessor, 實現其postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            //如果beanFactory不是BeanDefinitionRegistry
            //方法傳入普通BeanFactoryPostProcessor, 實現其postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        //處理beanFactory中注冊的普通BeanFactoryPostProcessor
        //非BeanDefinitionRegistryPostProcessor類型后置處理器
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                //說明已經處理過了
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //優先處理實現了PriorityOrdered接口的子類
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                //再處理實現了Ordered接口的子類
                orderedPostProcessorNames.add(ppName);
            }
            else {
                //最后處理其他BeanFactoryPostProcessor
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        //實現了PriorityOrdered接口的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);

        // 清除緩存
        beanFactory.clearMetadataCache();
    }
}

8.注冊bean處理器 registerBeanPostProcessors(beanFactory)

BeanPostProcessor是一個接口, Bean后置處理器, 在bean實例化, 之前執行postProcessBeforeInitialization方法, 在bean實例化之后執行postProcessAfterInitialization方法, 實現了對bean實例的增強

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
        
    //注冊beanPostProcessors
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
}
PostProcessorRegistrationDelegate.registerBeanPostProcessors

beanFactory中獲取BeanPostProcessor類型的bean名稱, 維護到postProcessorNames數組中, 將BeanPostProcessor列表分為四類:

  1. 實現了PriorityOrdered接口, 維護到priorityOrderedPostProcessors列表中
  2. 實現了Ordered接口的BeanPostProcessor, 維護到orderedPostProcessorNames列表中
  3. 沒有實現排序接口的, 維護到nonOrderedPostProcessorNames列表中
  4. 實現了MergedBeanDefinitionPostProcessor接口, 維護到internalPostProcessors列表中

beanFactory先添加一個BeanPostProcessorChecker類型的BeanPostProcessor, 然后在將各類PostProcessors列表排序, 分別添加到beanFactory的beanPostProcessor列表中, 最后再添加一個ApplicationListenerDetector

final class PostProcessorRegistrationDelegate {
    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 添加一個BeanPostProcessorChecker 
        // beanFactory數量不符合時,會打印info日志
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // BeanPostProcess分類
        // 實現了PriorityOrdered接口
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        //實現了MergedBeanDefinitionPostProcessor接口
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        // 實現了Ordered接口
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 沒有實現排序接口
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //PriorityOrdered子類
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    //MergedBeanDefinitionPostProcessor子類
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                // Ordered子類
                orderedPostProcessorNames.add(ppName);
            }
            else {
                // 普通BeanPostProcessor
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 實現了PriorityOrdered接口的BeanPostProcessor, 先排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 然后添加到beanFactory中
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 實現了Ordered接口的BeanPostProcessor
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String ppName : orderedPostProcessorNames) {
            // 先從beanFactory中獲取bean
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            // 然后添加到orderedPostProcessors列表中
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 如果是MergedBeanDefinitionPostProcessor的子類
                // 那么加入internalPostProcessors中
                internalPostProcessors.add(pp);
            }
        }
        // 排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 添加到beanFactory中
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 添加其他BeanPostProcessor
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                   // 如果是MergedBeanDefinitionPostProcessor的子類
                // 那么加入internalPostProcessors中
                internalPostProcessors.add(pp);
            }
        }
        // 添加到beanFactory中
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // 最后internalPostProcessors排序
        // 添加到beanFactory中
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // 添加一個ApplicationListenerDetector的beanFactory
        // 處理ApplicationListener類型的bean
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
}

9.國際化 initMessageSource()

先判斷容器beanFactory中是否包含messageSource bean定義, 存在的話, 直接獲取bean, 如果不存在的話, 那么手工注冊一個messageSource單例bean, 然后賦值給this.messageSource

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //判斷容器中是否包含messageSource bean定義
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            //容器中存在bean定義, 那么直接獲取bean
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                //HierarchicalMessageSource可以實現消息的嵌套
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            //容器中沒有messageSource bean定義
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            //手工注冊一個單例messageSource bean
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
            }
        }
    }

10. 注冊事件發布器 initApplicationEventMulticaster()

先判斷容器beanFactory中是否有applicationEventMulticaster bean定義, 存在的話, 獲取bean實例, 不存在的話, 實例化一個SimpleApplicationEventMulticaster, 手工注冊一個單例bean, 然后賦值給this.applicationEventMulticaster

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //先判斷容器beanFactory中是否有applicationEventMulticaster bean定義
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            //存在的話, 獲取bean實例
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isTraceEnabled()) {
                logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {
            //容器中不存在的話, 實例化一個SimpleApplicationEventMulticaster  
            //手工注冊一個單例bean
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }
    }

11. 通知子類刷新刷新容器 onRefresh()

AbstractApplicationContext沒有實現該方法, 用于通知子類刷新容器

ServletWebServerApplicationContext

調用父類GenericWebApplicationContext#onRefresh方法, 然后創建webServer, 之后調用父類GenericWebApplicationContext#initPropertySources方法, 將servletContext維護到environment的servletContextInitParams屬性中

public class ServletWebServerApplicationContext extends GenericWebApplicationContext
        implements ConfigurableWebServerApplicationContext {
    
    @Override
    protected void onRefresh() {
        //調用父類onRefresh方法
        super.onRefresh();
        try {
            //創建webServer
            createWebServer();
        }
        catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }
    
    //創建webServer
    private void createWebServer() {
        WebServer webServer = this.webServer;
        //默認servletContext為null
        ServletContext servletContext = getServletContext();
        if (webServer == null && servletContext == null) {
            //獲取一個ServletWebServerFactory
            ServletWebServerFactory factory = getWebServerFactory();
            //factory獲取一個webServer
            this.webServer = factory.getWebServer(getSelfInitializer());
        }
        else if (servletContext != null) {
            try {
                //servletContext不為空
                getSelfInitializer().onStartup(servletContext);
            }
            catch (ServletException ex) {
                throw new ApplicationContextException("Cannot initialize servlet context",
                        ex);
            }
        }
        
        //初始化
        initPropertySources();
    }
}
GenericWebApplicationContext

初始化主題, 可以讓頁面顯示不同的樣式

public class GenericWebApplicationContext extends GenericApplicationContext
        implements ConfigurableWebApplicationContext, ThemeSource {
    @Override
    protected void onRefresh() {
        //初始化資源
        this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }
}

12.注冊監聽器 registerListeners()

首先將硬編碼的ApplicationListener先添加this.applicationEventMulticaster.defaultRetriever.applicationListeners中, 然后將注入的listener bean維護到this.applicationEventMulticaster.defaultRetriever.applicationListenerBeans, 最后處理earlyEvent

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    protected void registerListeners() {
        // 首先將硬編碼的ApplicationListener先添加applicationEventMulticaster中
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // 然后將注入的listener bean維護到applicationEventMulticaster中
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 處理earlyEvent
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }
}

13. 完成beanFactory初始化, 實例化所有非延遲加載的bean

beanFactory.preInstantiateSingletons() 源碼剖析

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化ConversionService的實例化
        // 然后賦值給beanFactory.conversionService實例
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // 如果beanFactory中沒有@Value解析器
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 類加載期間織入的切面
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            //實例化所有LoadTimeWeaverAware類型的bean
            getBean(weaverAwareName);
        }

        //停止使用臨時ClassLoader
        beanFactory.setTempClassLoader(null);

        //凍結配置,不再允許改變
        beanFactory.freezeConfiguration();

        //實例化所有非延遲加載的bean
        beanFactory.preInstantiateSingletons();
    }
}

14.完成刷新 finishRefresh()

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    protected void finishRefresh() {
        // 清空緩存
        clearResourceCaches();

        // 初始化一個LifecycleProcessor
        // 在Spring啟動的時候啟動bean
        // 在spring結束的時候銷毀bean
        initLifecycleProcessor();

        // 調用LifecycleProcessor的onRefresh方法
        // 啟動實現了Lifecycle接口的bean
        getLifecycleProcessor().onRefresh();

        // 發布ContextRefreshedEvent
        publishEvent(new ContextRefreshedEvent(this));

        // 如果配置了"spring.liveBeansView.mbeanDomain"的系統屬性,制定了MBeanServer,
        // 那么會將ApplicationContext注冊到MBeanServer中,
        // 可以通過MBeanServer,對spring容器中的bean,進行實時的查看和管理
        LiveBeansView.registerApplicationContext(this);
    }
}
發布ContextRefreshedEvent
DelegatingApplicationListener

什么都沒有做

ConditionEvaluationReportListener

打印@Condition注解評估日志

public class ConditionEvaluationReportLoggingListener
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    protected void onApplicationEvent(ApplicationEvent event) {
        ConfigurableApplicationContext initializerApplicationContext = this.applicationContext;
        if (event instanceof ContextRefreshedEvent) {
            //打印刷新成功日志
            if (((ApplicationContextEvent) event)
                    .getApplicationContext() == initializerApplicationContext) {
                logAutoConfigurationReport();
            }
        }
        else if (event instanceof ApplicationFailedEvent
                && ((ApplicationFailedEvent) event)
                        .getApplicationContext() == initializerApplicationContext) {
            //打印失敗日志
            logAutoConfigurationReport(true);
        }
    }
}
ClearCachesApplicationListener

清空ReflectionUtils的緩存, 遞歸清空classLoader緩存

class ClearCachesApplicationListener
        implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ReflectionUtils.clearCache();
        clearClassLoaderCaches(Thread.currentThread().getContextClassLoader());
    }
}
SharedMetadataReaderFactoryBean
static class SharedMetadataReaderFactoryBean
            implements FactoryBean<ConcurrentReferenceCachingMetadataReaderFactory>,
            BeanClassLoaderAware, ApplicationListener<ContextRefreshedEvent> {
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //清空metadataReaderFactory的緩存
        this.metadataReaderFactory.clearCache();
    }
}
ResourceUrlProvider
public class ResourceUrlProvider implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //默認為true
        if (isAutodetect()) {
            //自動推斷pattern對應的ResourceHttpRequestHandler
            this.handlerMap.clear();
            detectResourceHandlers(event.getApplicationContext());
            if (!this.handlerMap.isEmpty()) {
                this.autodetect = false;
            }
        }
    }
}

15. 異常處理

    //beanFactory銷毀注冊的bean
    destroyBeans();

    //ApplicationContext取消刷新
    cancelRefresh(ex);

16. 清除緩存 resetCommonCaches()

    protected void resetCommonCaches() {
        //反射工具類的緩存清空
        ReflectionUtils.clearCache();
        //注解工具類的緩存清空
        AnnotationUtils.clearCache();
        //ResolvableType的緩存清空
        ResolvableType.clearCache();
        //清空ClassLoader
        CachedIntrospectionResults.clearClassLoader(getClassLoader());
    }

總結

本文主要分析了spring容器的刷新, 首先更新刷新狀態, 然后處理beanFactory的后置處理器, 用于注冊bean定義, 其中ConfigurationClassPostProcessor處理器, 處理模塊中@Configuration注解, onRefresh()方法中, 實例化了TomcatWebServer, 最后在finishRefresh()中, 實例化了所有bean

下一篇

我們將會在下一篇啟動完成, 研究springboot啟動完成的操作

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容