spring源碼解析 -- Spring Context

源碼分析基於spring 4.3.xjava

本文經過閱讀源碼分析Spring Context​。
關於閱讀源碼的思路,可參考 -- 如何閱讀java源碼spring

前面解析spring構造bean過程的文章說過期,spring會查找上下文中用戶定義的BeanPostProcessor並進行相應操做,那麼這些擴展的BeanPostProcessor是怎樣進入spring的呢?
這裏就要說到Spring Context模塊了。springboot

Spring Context模塊增長了對國際化(例如使用資源包),事件傳播,資源加載,透明建立上下文(如Servlet容器)的支持,而將用戶定義的BeanPostProcessor加載到spring,正是Spring Context的工做。微信

ApplicationContext接口是Context模塊的核心。
AbstractApplicationContext是ApplicationContext接口的基礎實現類。多線程

核心方法AbstractApplicationContext#refreshapp

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        
        prepareRefresh();    // #1

        
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();    // #2


        prepareBeanFactory(beanFactory);    // #3

        try {
            postProcessBeanFactory(beanFactory);    // #4


            invokeBeanFactoryPostProcessors(beanFactory);    // #5

            registerBeanPostProcessors(beanFactory);    // #6

            initMessageSource();    // #7

            
            initApplicationEventMulticaster();    // #8

            onRefresh();    // #9

            registerListeners();    // #10

            
            finishBeanFactoryInitialization(beanFactory);    // #11

            finishRefresh();    // #12
        }
        catch (BeansException ex) {
            ...
            destroyBeans();    // #13
            
            cancelRefresh(ex);    // #14
            
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

#1 準備刷新上下文環境
#2 初始化BeanFactory,並加載bean definitions信息
#3 對beanFacotry進行配置
#4 提供給子類擴展的預留方法
#5 激活BeanFactoryPostProcessors
#6 註冊BeanPostProcessors
#7 初始化MessageSource
#8 初始化事件廣播器
#9 提供給子類初始化其餘的Bean
#10 註冊事件監聽器
#11 構造熱加載單例bean
#12 完成刷新過程,通知生命週期處理器
#13 出錯了,銷燬bean
#14 出錯了,修改active標識ide

AbstractApplicationContext#obtainFreshBeanFactory -> AbstractRefreshableApplicationContext#refreshBeanFactory源碼分析

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {    // #1
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();    // #2
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);    // #3
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

#1 若是已存在BeanFactory,銷燬原來的BeanFactory
#2 建立DefaultListableBeanFactory
#3 加載bean definitions信息,loadBeanDefinitions是抽象方法,不一樣實現類會從不一樣的配置中獲取bean definitions信息,如AnnotationConfigWebApplicationContext,XmlWebApplicationContext。post

激活BeanFactoryPostProcessors

BeanFactoryPostProcessor是spring提供的擴展接口,能夠經過BeanFactoryPostProcessor對beanFactory進行自定義處理,如修改其餘BeanDefinition的配置。this

AbstractApplicationContext#invokeBeanFactoryPostProcessors -> PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

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

    Set<String> processedBeans = new HashSet<String>();

    if (beanFactory instanceof BeanDefinitionRegistry) {    // #1
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                new LinkedList<BeanDefinitionRegistryPostProcessor>();

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {    // #2
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);    // #3

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));        // #4
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);        // #5
        registryPostProcessors.addAll(priorityOrderedPostProcessors);    // #6
        invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);    // #7

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {    // #8
                orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);    
        registryPostProcessors.addAll(orderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);    

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {    // #9
                    BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                    registryPostProcessors.add(pp);
                    processedBeans.add(ppName);
                    pp.postProcessBeanDefinitionRegistry(registry);
                    reiterate = true;
                }
            }
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);    
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);    
    }

    ...
}

BeanFactoryPostProcessor能夠調整beanFactory,甚至修改BeanDefinition,如CustomEditorConfigurer,將用戶定義的PropertyEditor註冊到beanFactory中,以便後續使用。
BeanDefinitionRegistryPostProcessor能夠註冊新的BeanDefinition,如ConfigurationClassPostProcessor,是實現springboot很關鍵的類

#1 若是beanFactory是BeanDefinitionRegistry,須要處理BeanFactoryPostProcessors,BeanDefinitionRegistryPostProcessor,不然只處理BeanFactoryPostProcessors
#2 方法參數beanFactoryPostProcessors是AbstractApplicationContext#beanFactoryPostProcessors屬性,用戶能夠經過AbstractApplicationContext#addBeanFactoryPostProcessor方法添加BeanFactoryPostProcessor。這裏對beanFactoryPostProcessors參數進行分類
#3 獲取beanFactory已經存在的BeanDefinitionRegistryPostProcessor 這裏並無直接構建BeanDefinitionRegistryPostProcessor,並且經過beanName獲取
#4 獲取實現了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,添加到priorityOrderedPostProcessors
#5 對priorityOrderedPostProcessors排序
#6 排序結果添加到registryPostProcessors
#7 調用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
#8 處理實現了Ordered的BeanDefinitionRegistryPostProcessor
#9 處理剩餘的BeanDefinitionRegistryPostProcessor

beanFactoryPostProcessors的處理不在貼出了。

註冊BeanPostProcessors

PostProcessorRegistrationDelegate#registerBeanPostProcessors會找到用戶定義的BeanPostProcessor, 並註冊到spring中,spring構造bean時會使用到它們。

PostProcessorRegistrationDelegate#registerBeanPostProcessors相似,獲取上下文中的BeanPostProcessor,不過這裏不會調用BeanPostProcessor的方法,只是註冊到beanFactory中,在構建bean時再調用BeanPostProcessors對應的方法。
PostProcessorRegistrationDelegate#registerBeanPostProcessors

private static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}

初始化事件廣播器

Spring事件體系包括三個組件:ApplicationEvent事件,ApplicationListener事件監聽器,ApplicationEventMulticaster事件廣播器。
事件廣播器負責管理事件監聽器,並將事件廣播給監聽器。
AbstractApplicationContext#initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);    //#1
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);    //#2
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

#1 使用用戶定義的事件廣播器
#2 使用默認的事件廣播器

spring提供了context start,stop,close,refresh等事件,ApplicationListener#onApplicationEvent負責處理spring中的事件。咱們能夠經過實現ApplicationListener接口自行處理事件,也能夠經過PublishListener自定義事件監聽器。

使用默認的事件廣播器 AbstractApplicationContexton#publishEvent -> SimpleApplicationEventMulticaster#multicastEvent

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();    // #1
        if (executor != null) {
            executor.execute(new Runnable() {
                public void run() {
                    invokeListener(listener, event);
                }
            });
        }
        else {
            invokeListener(listener, event);    // #2
        }
    }
}

#1 若是配置了Executor,使用Executor多線程處理
#2 不然單線程處理
事件處理就是遍歷全部的事件監聽器,調用ApplicationListener#onApplicationEvent。

註冊事件監聽器

AbstractApplicationContext#registerListeners將初始化事件監聽器ApplicationListener,並綁定到事件廣播器上。

protected void registerListeners() {
    for (ApplicationListener<?> listener : getApplicationListeners()) {    // #1
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);    // #2
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

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

#1 getApplicationListeners()獲取的是AbstractApplicationContext#applicationListeners,用戶能夠經過AbstractApplicationContext#addApplicationListener添加事件監聽器
將AbstractApplicationContext#applicationListeners註冊到applicationEventMulticaster
#2 將上下文中的ApplicationListener註冊到applicationEventMulticaster
#3 發佈在此以前已發生的事件

構造熱加載單例bean

AbstractApplicationContext#finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    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));    //#1
    }

    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {    //#2
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);    //#3
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    beanFactory.setTempClassLoader(null);

    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();    //#4
}

#1 初始化ConversionService,後面注入屬性要使用
#2 初始化StringValueResolver,用於解析bean屬性引用的properties配置
#3 初始化LoadTimeWeaverAware
#4 構造熱加載單例bean

AbstractApplicationContext#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
    ...

    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {    // #1
            if (isFactoryBean(beanName)) {
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
            }
            else {
                getBean(beanName);    // #2
            }
        }
    }
    ...
}

#1 判斷是否爲非抽象類的熱加載單例bean
#2 構造bean
若是非FactoryBean,構造bean。
若是FactoryBean而且FactoryBean.isEagerInit爲true,構造bean。

finishRefresh

protected void finishRefresh() {
    // Initialize lifecycle processor for this context.
    initLifecycleProcessor();    // #1

    // Propagate refresh to lifecycle processor first.
    getLifecycleProcessor().onRefresh();    // #2

    // Publish the final event.
    publishEvent(new ContextRefreshedEvent(this));    // #4

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

#1 初始化LifecycleProcessor
#2 調用LifecycleProcessor#onRefresh()方法
#3 發佈事件

LifecycleProcessor也是spring提供的擴展點, 經過它能夠在spring content start,stop,onRefresh等時刻自定義一些額外操做。

這裏主要講了spring context的相關內容,講的比較簡單, 有興趣的同窗能夠自行深刻閱讀源碼。

若是您以爲本文不錯,歡迎關注個人微信公衆號,您的關注是我堅持的動力!

相關文章
相關標籤/搜索