SpringBoot項目啓動過程源碼終於整體捋了一遍(九)

上篇介紹了run()方法中context三連中的prepareContext()方法,先貼一下這個三連:

這篇的重點是refreshContext()方法,先看一下這個方法:

接下來的方法比較多,想着自己寫有點懶了,看到其他文章中直接在源碼中添加註釋的方法還挺直觀的 ,接下來就當一下搬運工,自己也補充了部分地方,下面的原文出處:

作者:ygxing
鏈接:https://www.jianshu.com/p/7317626794fa
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

先看refresh()方法,這個方法最終主要邏輯在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();
            }
        }
    }
}

具體的還需要一個一個方法的看。

一.準備刷新prepareRefresh():

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

看一下其父類AbstractApplicationContext的prepareRefresh:

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<>();
    }
}

二.獲取並刷新obtainFreshBeanFactory();

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;
    }
}

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

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;
    }
}

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

三.prepareBeanFactory(beanFactory)準備beanFactory

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());
        }
    }
}

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

  • 配置classLoader爲當前context的classLoader
  • 設置BeanExpressionResolver, 解析EL表達式
  • 設置屬性編輯器
  • 添加BeanPostProcessor
  • 配置自動裝配
  • 手工註冊environment相關bean

四.beanFactory的後置處理器 postProcessBeanFactory(beanFactory)

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));
        }
    }

}

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

  • 調用了父類方法
  • 判斷basePackages是否爲空, 不爲空的話, 掃描this.basePackages
  • 判斷annotatedClasses是否爲空, 不爲空的話, 註冊bean

其父類的postProcessBeanFactory()方法:

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();
    }
}

進行了兩個操作, 首先添加了一個WebApplicationContextServletContextAwareProcessor的Aware Bean處理器, ServletContextAware的子類Bean在實例化過程中, 會被注入servletContext和servletConfig對象, 然後beanFactory中註冊了request和session兩個scopes, 註冊了幾個Autowired依賴類。看一下這個registerWebApplicationScopes()方法:

這裏的ExistingWebApplicationScopes簡單介紹一下,第二篇(https://blog.csdn.net/weixin_42447959/article/details/104943589)中有提到@scope註解,它的value可以設置爲以下幾種:
單例(singleton):在整個應用中,只創建bean的一個實例。
原型(prototype):每次注入或者通過Spring應用上下文獲取的時候,都會創建一個新的實例。
會話(session):在Web應用中,爲每個會話創建一個bean實例。
請求(request):在Web應用中,爲每個請求創建一個bean實例。

這裏注意session和request都是在Web應用中才有的,這個ExistingWebApplicationScopes就是註冊了這兩種scope類型,具體就不點進去看了,感興趣的可以看一下。重點還是WebApplicationContextUtils的registerWebApplicationScopes()方法:

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);
        }
    }
}

上面說到註冊了session和request這兩種scope類型,這裏面又註冊ServletRequest, ServletResponse, HttpSession,和WebRequest這四個。

五.invokeBeanFactoryPostProcessors(beanFactory)實例化並調用beanFactory所有已註冊的後置處理器

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()));
    }
}

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

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

看一下PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法:

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();
    }
}

如果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

     2.然後處理實現了Ordered接口的BeanDefinitionRegistryPostProcessor, 一共分爲5個步驟

  • 先判斷processedBeans中是否包含了beanName, 如果包含了就不處理
  • 生成bean, 維護到currentRegistryProcessors列表中
  • processedBeans中添加bean名稱, 標記已經被處理
  • currentRegistryProcessors列表排序, 並添加到registryProcessors中
  • 遍歷registryProcessors列表, 調用每個元素的postProcessBeanDefinitionRegistry方法
  • 然後清空currentRegistryProcessors

     3.處理剩下的所有BeanDefinitionRegistryPostProcessor, 方法同第2步

     4.遍歷registryProcessors, 調用其postProcessBeanFactory方法

     5.遍歷所有的regularPostProcessors, 調用其postProcessBeanFactory方法

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

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

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

2.然後處理實現了Ordered接口的BeanFactoryPostProcessor, 方法同上

3.最後處理其他BeanFactoryPostProcessor, 方法同上

ConfigurationClassPostProcessor處理了@Configuration註解, 掃描項目中的BeanDefinition。

六.註冊bean處理器 registerBeanPostProcessors(beanFactory)

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

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

看一下這個registerBeanPostProcessors()方法:

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));
    }
}

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

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

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

七.國際化 initMessageSource()

    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 + "]");
            }
        }
    }

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

八.註冊事件發佈器 initApplicationEventMulticaster()

    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() + "]");
            }
        }
    }

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

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

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();
    }
}

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

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

其父類的onRefresh():

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

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

十.註冊監聽器 registerListeners()

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);
            }
        }
    }
}

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

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

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();
    }
}

十二.完成刷新 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);
    }
}

十三.異常處理

    //beanFactory銷燬註冊的bean
    destroyBeans();

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

十四.清除緩存 resetCommonCaches()

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

最後總結一下,這個過程主要分析了spring容器的刷新, 首先更新刷新狀態, 然後處理beanFactory的後置處理器, 用於註冊bean定義, 其中ConfigurationClassPostProcessor處理器, 處理模塊中@Configuration註解, onRefresh()方法中, 實例化了TomcatWebServer, 最後在finishRefresh()中, 實例化了所有bean。

嚯,一下子搬了這麼多,到這裏context三連的第二連refreshContext()其實還沒寫完,搬了有點多再貼一遍這個方法:

這才分析了refresh()方法,其實下面的shutdownHook也值得專門一篇文章,下篇不搬了好好總結,這篇就不總結了,直接接下篇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章