1. 程式人生 > >Spring系列(三):Spring IoC原始碼解析

Spring系列(三):Spring IoC原始碼解析

一、Spring容器類繼承圖

二、容器前期準備

  IoC原始碼解析入口:

/**
 * @desc: ioc原理解析 啟動
 * @author: toby
 * @date: 2019/7/22 22:20
 */
public class PrincipleMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrincipleConfig.class);
    }
}

  呼叫建構函式AnnotationConfigApplicationContext

  呼叫this(),會預設先呼叫父類的無參建構函式,為ApplicationContext上下文物件初始beanFactory = new DefaultListableBeanFactory()

  在呼叫當前類的this(),也就是呼叫自己的無參建構函式:

    進到建立註解模式下的Bean定義讀取器:

  org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object) 主要是註冊Spring自身的一些後置處理器

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

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        /**
         * 為我們容器中註冊解析主配置類的後置處理器ConfigurationClassPostProcessor
         * beanName = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
         */
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        /**
         * 為我們容器中註冊處理@Autowired註解的Bean的後置處理器AutowiredAnnotationBeanPostProcessor
         * beanName = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
         */
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        /**
         * 為我們容器中註冊處理@Required屬性註解的Bean後置處理器RequiredAnnotationBeanPostProcessor
         * beanName = org.springframework.context.annotation.internalRequiredAnnotationProcessor
         */
        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        /**
         * 為我們容器註冊處理JSR規範註解的Bean後置處理器CommonAnnotationBeanPostProcessor
         * beanName = org.springframework.context.annotation.internalCommonAnnotationProcessor
         */
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        /**
         * 為我們容器註冊處理jpa的Bean的後置處理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
         */
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        /**
         * 處理監聽方法的註解解析器EventListenerMethodProcessor
         */
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        /**
         * 註冊事件監聽器工廠
         */
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }

  讀取器初始化完成後,Spring的容器的Bean的定義資訊就有Spring自身的一些後置處理器了,Debug如下:

  讀取器初始化完成後,接下來初始化ClassPath下的Bean定義掃描器:

     org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(org.springframework.beans.factory.support.BeanDefinitionRegistry, boolean, org.springframework.core.env.Environment, org.springframework.core.io.ResourceLoader) 類路徑下的Bean定義掃描

 

   org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#registerDefaultFilters 注入預設的Filter

protected void registerDefaultFilters() {
        this.includeFilters.add(new AnnotationTypeFilter(Component.class));
        ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
        try {
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
            logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
            // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
        }
        try {
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
            logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - simply skip.
        }
    }

  這裡需要注意的是為什麼new AnnotationTypeFilter(Component.class)就可以處理@Repository,@Service,@Controller這3個註解,原因如下:

  自此前期準備工作完成

三、org.springframework.context.support.AbstractApplicationContext#refresh 12大步

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //1:準備重新整理上下文環境
            prepareRefresh();

            //2:獲取初始化Bean工廠
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //3:對bean工廠進行填充屬性
            prepareBeanFactory(beanFactory);

            try {
                //4:Spring開放介面 留給子類去實現該介面
                postProcessBeanFactory(beanFactory);

                //5:呼叫我們的bean工廠的後置處理器
                invokeBeanFactoryPostProcessors(beanFactory);

                //6:註冊我們bean後置處理器
                registerBeanPostProcessors(beanFactory);

                //7:初始化國際化資源處理器
                initMessageSource();

                //8:初始化事件多播器
                initApplicationEventMulticaster();

                //9:這個方法同樣也是留個子類實現,其中springboot也是從這個方法進行tomcat的啟動
                onRefresh();

                //10:把我們的事件監聽器註冊到多播器上
                registerListeners();

                //11:例項化所有的非懶載入的單例項bean
                finishBeanFactoryInitialization(beanFactory);

                //12:最後重新整理容器 釋出重新整理事件(Spring cloud eureka也是從這裡啟動的)
                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...
                resetCommonCaches();
            }
        }
    }

  第一步:prepareRefresh()

  準備重新整理上下文環境:

protected void prepareRefresh() {
        // Switch to active.
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        /**
         * 初始化上下文環境
         */
        initPropertySources();

        /**
         * 用來校驗我們容器啟動必須依賴的環境變數的值
         */
        getEnvironment().validateRequiredProperties();

        /**
         * 建立一個早期事件監聽器物件
         */
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            // Reset local application listeners to pre-refresh state.
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        /**
         * 建立一個容器用於儲存早期待發布的事件集合 什麼是早期事件了?
         * 就是我們的事件監聽器還沒有註冊到事件多播器上的時候都稱為早期事件
         */
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

  第二步:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() 

  獲取初始化的Bean的工廠:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        //重新整理bean工廠()
        refreshBeanFactory();
        //返回之前容器準備工作的時候建立的的bean工廠也就是DefaultListableBeanFactory(很重要)
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

  org.springframework.context.support.GenericApplicationContext#refreshBeanFactory,注意只能刷一次

protected final void refreshBeanFactory() throws IllegalStateException {
        //由於BeanFactory只能重新整理一次,多執行緒情況下可能導致執行緒安全問題,所有使用cas原子操作來保證
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException(
                    "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        }
        //指定Bean工廠的序列化Id
        this.beanFactory.setSerializationId(getId());
    }

   第三步:prepareBeanFactory(beanFactory)

  對bean工廠進行填充屬性:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //設定bean工廠的類載入器為當前application應用上下文的載入器
        beanFactory.setBeanClassLoader(getClassLoader());
        //為bean工廠設定SPEL表示式解析器物件StandardBeanExpressionResolver
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //為我們的bean工廠設定了一個propertyEditor屬性資源編輯器物件(用於後面的給bean物件賦值使用)
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
        //註冊ApplicationContextAwareProcessor後置處理器用來處理ApplicationContextAware介面的回撥方法
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        /**
         * 當Spring將ApplicationContextAwareProcessor註冊後,那麼在invokeAwarelnterfaces方法中呼叫的Aware類已經不是普通的bean了 ,
         * 如ResourceLoaderAware、ApplicationEventPublisherAware、ApplicationContextAware等,那麼當然需要在Spring做bean的依賴注入的時候忽略它們。
         * 這個就是ignoreDependencyInterface的作用
         */
        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.class的解析依賴後,
         * 當bean的屬性注入的時候,一旦檢測到屬性為BeanFactory型別便會將beanFactory的例項注入進去。
         */
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        //註冊了一個事件監聽器探測器後置處理器介面
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
        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()));
        }
        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());
        }
    }

  第四步:postProcessBeanFactory(beanFactory)

  Spring開放介面留給子類去實現該介面:主要用來改變BeanFactory比如給BeanFactory新增一些自己的BeanPostProcessor(Bean的後置處理器)

  第五步:invokeBeanFactoryPostProcessors(beanFactory)

  呼叫我們的bean工廠的後置處理器:詳解見:Spring IoC原始碼解析之invokeBeanFactoryPostProcessors

  第六步:registerBeanPostProcessors(beanFactory)

  註冊我們bean後置處理器:

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)

/**
     * 往容器中註冊了我們的bean的後置處理器
     * bean的後置處理器在什麼時候進行呼叫?在bean的生命週期中
     * @param beanFactory
     * @param applicationContext
     */
    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        //去容器中獲取所有的BeanPostProcessor的bean名稱
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        /**
         * beanFactory.getBeanPostProcessorCount()獲取的是已經新增在beanFactory的beanPostProcessors集合中的
         * postProcessorNames.length  beanFactory工廠中BeanPostProcessor個數 +1 又註冊了BeanPostProcessorChecker的後置處理器
         */
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        /**
         * 按照BeanPostProcessor實現的優先順序介面來分離我們的後置處理器
         */
        //儲存實現了priorityOrdered介面的
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        //容器內部的
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        //實現了我們ordered介面的
        List<String> orderedPostProcessorNames = new ArrayList<>();
        //實現了我們任何優先順序的
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        //迴圈我們的bean定義(BeanPostProcessor)
        for (String ppName : postProcessorNames) {
            //若實現了PriorityOrdered介面的
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //顯示的呼叫getBean流程建立bean的後置處理器
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                //加入到集合中
                priorityOrderedPostProcessors.add(pp);
                //判斷是否實現了MergedBeanDefinitionPostProcessor
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    //加入到集合中
                    internalPostProcessors.add(pp);
                }
            }
            //判斷是否實現了Ordered
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        //把實現了priorityOrdered註冊到容器中
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        //處理實現Ordered的bean後置處理器
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String ppName : orderedPostProcessorNames) {
            //顯示呼叫getBean方法
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            //加入到集合中
            orderedPostProcessors.add(pp);
            //判斷是否實現了MergedBeanDefinitionPostProcessor
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                //加入到集合中
                internalPostProcessors.add(pp);
            }
        }
        //排序並且註冊我們實現了Order介面的後置處理器
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 例項化我們所有的非排序介面的
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {
            //顯示呼叫
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            //判斷是否實現了MergedBeanDefinitionPostProcessor
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //註冊我們普通的沒有實現任何排序介面的
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        //註冊MergedBeanDefinitionPostProcessor型別的後置處理器
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        //註冊ApplicationListenerDetector應用監聽器探測器的後置處理器
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

  第七步:initMessageSource()

  初始化國際化資源處理器:

/**
     * Initialize the MessageSource.
     * Use parent's if none defined in this context.
     */
    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // Make MessageSource aware of parent MessageSource.
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // Only set parent context as parent MessageSource if no parent MessageSource
                    // registered already.
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            // Use empty MessageSource to be able to accept getMessage calls.
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                        "': using default [" + this.messageSource + "]");
            }
        }
    }

  第八步:initApplicationEventMulticaster()

  初始化事件多播器:

/**
     * 從bean工廠中獲取或者直接顯示的new一個事件多播器賦值給applicatoinContext物件的applicationEventMulticaster屬性
     * 事件多播器採用典型的設計模式就是觀察者模式 多播器作為的是一個被觀察者
     * @see org.springframework.context.event.SimpleApplicationEventMulticaster
     */
    protected void initApplicationEventMulticaster() {
        //獲取我們的bean工廠物件
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //判斷容器中是否包含了applicationEventMulticaster事件多播器元件
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            //直接顯示的呼叫我們的getBean獲取出來賦值給我們的applicationContext物件
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        //容器中沒有的話
        else {
            //直接new一個
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            //並且注入到容器中
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

  第九步:onRefresh()

  這個方法很重要同樣也是留個子類實現,其中Spring Boot就是從這個方法進行tomcat的啟動(後續講Spring Boot的原始碼分析的時候會涉及到這塊,比如:Spring容器的啟動如何帶動web容器tomcat的啟動以及web容器tomcat的啟動如何帶動Spring容器的啟動)

  第十步:registerListeners()

  把我們的事件監聽器註冊到事件多播器上:

protected void registerListeners() {
        //獲取容器中所有的監聽器物件
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            //把監聽器挨個的註冊到我們的事件多播器上去
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        //獲取bean定義中的監聽器物件
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        //把監聽器的名稱註冊到我們的事件多播器上
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        //在這裡獲取我們的早期事件
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            //通過多播器進行播發早期事件
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

  如何釋出事件,通過事件多播器方法:multicastEvent(ApplicationEvent event),進入方法

@Override
    public void multicastEvent(ApplicationEvent event) {
        multicastEvent(event, resolveDefaultEventType(event));
    }

  multicastEvent(event, resolveDefaultEventType(event))方法:

@Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        //從事件多播器中獲取出所有的監聽器
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            //判斷多播器中是否支援非同步多播的
            Executor executor = getTaskExecutor();
            if (executor != null) {
                //非同步播發事件
                executor.execute(() -> invokeListener(listener, event));
            }
            else {//同步播發
                invokeListener(listener, event);
            }
        }
    }

  invokeListener(listener, event)方法:

/**
     * Invoke the given listener with the given event.
     * @param listener the ApplicationListener to invoke
     * @param event the current event to propagate
     * @since 4.1
     */
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                doInvokeListener(listener, event);
            }
            catch (Throwable err) {
                errorHandler.handleError(err);
            }
        }
        else {
            doInvokeListener(listener, event);
        }
    }

  doInvokeListener(ApplicationListener listener, ApplicationEvent event) 方法(Spring有一個特點涉及到以do開頭的方法都是真正幹活的):

  第十一步:finishBeanFactoryInitialization(beanFactory)

   例項化所有的非懶載入的單例項bean:詳解見:Spring IoC原始碼解析之getBean

  第十二步:finishRefresh()

  最後重新整理容器釋出重新整理事件(Spring cloud eureka也是從這裡啟動的):

protected void finishRefresh() {

        //初始化生命週期處理器
        initLifecycleProcessor();

        //呼叫生命週期處理器的onRefresh方法
        getLifecycleProcessor().onRefresh();

        //釋出ContextRefreshedEvent事件
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }

  ① 初始化生命週期處理器:initLifecycleProcessor()方法:

protected void initLifecycleProcessor() {
        //獲取beanFactory工廠
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //判斷容器中是否有lifecycleProcessor,有就直接從容器中拿
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            this.lifecycleProcessor =
                    beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
            }
        }
        //沒有建立一個DefaultLifecycleProcessor,然後註冊到容器中
        else {
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate LifecycleProcessor with name '" +
                        LIFECYCLE_PROCESSOR_BEAN_NAME +
                        "': using default [" + this.lifecycleProcessor + "]");
            }
        }
    }

  ② 呼叫生命週期處理器的onRefresh方法:getLifecycleProcessor().onRefresh():org.springframework.context.support.DefaultLifecycleProcessor#onRefresh:

@Override
    public void onRefresh() {
        startBeans(true);
        this.running = true;
    }

  startBeans(true)方法:org.springframework.context.support.DefaultLifecycleProcessor#startBeans:主要的功能是找到Spring容器的Lifecycle型別的Bean,然後呼叫start()去啟動

private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
        for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
            Lifecycle bean = entry.getValue();
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(entry.getKey(), bean);
            }
        }
        if (!phases.isEmpty()) {
            List<Integer> keys = new ArrayList<Integer>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {
                phases.get(key).start();
            }
        }
    }

  start()方法:

  doStart(this.lifecycleBeans, member.name, this.autoStartupOnly)方法:

private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
        Lifecycle bean = lifecycleBeans.remove(beanName);
        if (bean != null && bean != this) {
            String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);
            for (String dependency : dependenciesForBean) {
                doStart(lifecycleBeans, dependency, autoStartupOnly);
            }
            //bean不在執行中並且(autoStartupOnly=false 或者 不是SmartLifecycle型別 或者 isAutoStartup() = true)
            if (!bean.isRunning() &&
                    (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
                }
                try {
                    //呼叫生命週期Lifecycle Bean的start()方法
                    bean.start();
                }
                catch (Throwable ex) {
                    throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Successfully started bean '" + beanName + "'");
                }
            }
        }
    }

  ③ 釋出ContextRefreshedEvent事件:主要就是呼叫前面第八步建立的事件多播器的釋出事件方法getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType):

protected void publishEvent(Object event, ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }

        // Decorate event as an ApplicationEvent if necessary
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<Object>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
            }
        }

        // Multicast right now if possible - or lazily once the multicaster is initialized
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // Publish event via parent context as well...
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

   

  總結:從Spring IoC的原始碼解析過程中,我們更加深入的瞭解容器的初始化,Bean的後置處理器,國際化,事件多播器釋出事件,Bean的建立,屬性的賦值,三級快取解決迴圈依賴問題,Lifecycle的作用,Spring場景應用:Spring系列(二):Spring IoC應用,Spring系列完整程式碼在碼雲:spring