1. 程式人生 > >Spring原始碼解析之ApplicationContext

Spring原始碼解析之ApplicationContext

閱讀須知

  • Spring原始碼版本:4.3.8
  • 文章中使用/* */註釋的方法會做深入分析

正文

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");

這句程式碼相信大家都很熟悉,我們用這句程式碼載入配置檔案來初始化Spring,下面我們就以這句程式碼作為入口來看一下Spring初始化都做了哪些工作:
ClassPathXmlApplicationContext:

public ClassPathXmlApplicationContext
(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); }

ClassPathXmlApplicationContext:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
    super(parent); // 設定父級環境物件,這裡傳入的是null
setConfigLocations(configLocations); /* 設定配置檔案路徑 */ if (refresh) { refresh(); /* 重新整理環境 */ } }

AbstractRefreshableConfigApplicationContext:

public void setConfigLocations(String... locations) {
    if (locations != null) {
        Assert.noNullElements(locations, "Config locations must not be null"
); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { // 解析配置檔案路徑中的特殊符號(如${}等)並設定配置檔案路徑 this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }

AbstractApplicationContext:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh(); /* 為重新整理做準備工作 */
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); /* 初始化BeanFactory,並解析配置 */
        prepareBeanFactory(beanFactory); /* 為BeanFactory填充功能 */
        try {
            /* 子類擴充套件對BeanFactory進行額外處理 */
            postProcessBeanFactory(beanFactory);
            /* 呼叫註冊的BeanFactoryPostProcessors的postProcessBeanFactory方法 */
            invokeBeanFactoryPostProcessors(beanFactory);
            /* 註冊BeanPostProcessors */
            registerBeanPostProcessors(beanFactory);
            /* 初始化MessageSource,用於國際化處理 */
            initMessageSource();
            /* 初始化應用事件廣播器 */
            initApplicationEventMulticaster();
            /* 子類擴充套件初始化一些個性化的bean */
            onRefresh();
            /* 找到ApplicationListener bean,並註冊 */
            registerListeners();
            /* 初始化剩下的所有非lazy-init的單例bean */
            finishBeanFactoryInitialization(beanFactory);
            /* 初始化LifecycleProcessor(生命週期處理器),發步對應的事件通知,如果配置了JMX,則註冊MBean */
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }
            /* 銷燬已經建立的單例Bean */
            destroyBeans();
            /* 重置active標記為false */
            cancelRefresh(ex);
            throw ex;
        } finally {
            resetCommonCaches();
        }
    }
}

AbstractApplicationContext:

protected void prepareRefresh() {
    // 設定初始化開始時間
    this.startupDate = System.currentTimeMillis(); 
    this.closed.set(false);
    this.active.set(true);
    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }
    initPropertySources(); // 初始化設定屬性,留給子類擴充套件,預設空實現
    // 校驗必須的屬性,使用者也可以根據個性化需求擴充套件必要屬性的校驗
    getEnvironment().validateRequiredProperties();
    this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

在進入下面的分析之前簡單介紹一下BeanFactory,BeanFactory提供Spring的IoC功能的基礎,字面理解就是bean工廠,用來定義和建立bean。
AbstractApplicationContext:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory(); /* 重新整理BeanFactory */
    ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 獲取BeanFactory
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

AbstractRefreshableApplicationContext:

protected final void refreshBeanFactory() throws BeansException {
    // 如果有BeanFactory,則銷燬已經建立的bean並關閉掉BeanFactory(將其置為null)
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 建立BeanFactory(DefaultListableBeanFactory)
        DefaultListableBeanFactory beanFactory = createBeanFactory(); 
        beanFactory.setSerializationId(getId()); // 設定序列化id
        customizeBeanFactory(beanFactory); /* 定製BeanFactory */
        loadBeanDefinitions(beanFactory); /* 載入BeanDefinition */
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

AbstractRefreshableApplicationContext:

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    // 設定是否允許覆蓋同名稱不同定義的物件
    if (this.allowBeanDefinitionOverriding != null) {
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    // 設定是否允許bean之間的迴圈依賴
    if (this.allowCircularReferences != null) {
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
}

載入BeanDefinition的流程也就是標籤解析的流程我們會在後面的文章進行單獨分析。
AbstractApplicationContext:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    // 設定SPEL表示式處理器,在bean初始化填充屬性時會用到
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 新增屬性編輯器註冊器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    // 新增Aware介面的BeanPostProcessor
    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);
    // 註冊幾個自動裝配的介面
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    // 新增用於發現ApplicationListener的BeanPostProcessor
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    // 增加對靜態AOP的支援
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    // 新增幾個預設的系統環境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());
    }
}

這裡提到了屬性編輯器和自動裝配的概念,這些我們會在bean建立的文章中進行講解,這裡先留一個懸念。簡單介紹一下方法中註冊的ApplicationContextAwareProcessor,它實現了BeanPostProcessor,Spring會保證所有bean在例項化的時候都會呼叫其postProcessAfterInitialization方法,我們可以使用這個方法包裝和改變bean,我們來看一下這個方法:
ApplicationContextAwareProcessor:

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    AccessControlContext acc = null;
    if (System.getSecurityManager() != null &&
            (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                    bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                    bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
        acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    }
    if (acc != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareInterfaces(bean); /* 呼叫Aware介面 */
                return null;
            }
        }, acc);
    }
    else {
        invokeAwareInterfaces(bean); /* 呼叫Aware介面 */
    }
    return bean;
}

ApplicationContextAwareProcessor:

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

當我們的bean實現了某個Aware介面,這裡就會呼叫相關的set方法為我們的bean設定相關資源。下一步的postProcessBeanFactory預設為空實現,留給子類擴充套件做BeanFactory初始化後的後置處理。接下來就是呼叫所有註冊的BeanFactoryPostProcessor的相關方法,我們以一個例子來說明一下BeanFactoryPostProcessor的用法,我們在使用Spring整合Mybatis的時候會配置一個類MapperScannerConfigurer,用來掃描我們工程中定義的所有Mapper介面,我們來看一下它的層次結構:
這裡寫圖片描述
這裡就會呼叫它的postProcessBeanDefinitionRegistry方法來掃描我們配置的包完成Mapper相關的BeanDefinition的註冊,我們會在Spring整合Mybatis的文章中進行詳細描述。
AbstractApplicationContext:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    /* 呼叫註冊的所有BeanFactoryPostProcessor的相關方法 */
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // 再次確認是否需要增加對靜態AOP的支援,這段邏輯在prepareBeanFactory方法中已經執行過,這裡因為有可能有新的BeanDefinition註冊,所以需要再次確認
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

PostProcessorRegistrationDelegate:

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    Set<String> processedBeans = new HashSet<String>();
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                new LinkedList<BeanDefinitionRegistryPostProcessor>();
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 首先呼叫BeanDefinitionRegistryPostProcessor 
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                        // 執行postProcessBeanDefinitionRegistry方法
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }
        // 從所有註冊的BeanDefinition中獲取BeanDefinitionRegistryPostProcessor
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            // 首先執行實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors); // 排序
        registryPostProcessors.addAll(priorityOrderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // 執行postProcessBeanDefinitionRegistry方法
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            // 接下來執行實現Ordered介面的BeanDefinitionRegistryPostProcessor
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors); // 排序
        registryPostProcessors.addAll(orderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // 執行
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 執行剩餘的BeanDefinitionRegistryPostProcessor
                if (!processedBeans.contains(ppName)) {
                    BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                    registryPostProcessors.add(pp);
                    processedBeans.add(ppName);
                    pp.postProcessBeanDefinitionRegistry(registry);
                    reiterate = true;
                }
            }
        }
        // BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor,執行完postProcessBeanDefinitionRegistry方法之後還要執行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }
    else {
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
            // 剩餘的BeanFactoryPostProcessor同樣按照實現PriorityOrdered --> 實現Ordered --> 其他的順序執行
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        // 上面已經將所有的BeanDefinitionRegistryPostProcessor都執行完了,這裡要將它們排除掉,執行剩餘的BeanFactoryPostProcessor
        if (processedBeans.contains(ppName)) {
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    beanFactory.clearMetadataCache();
}

下一步是註冊BeanPostProcessor:
AbstractApplicationContext:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    /* 註冊BeanPostProcessor */
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

PostProcessorRegistrationDelegate:

public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 獲取所有BeanPostProcessor的beanName
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 註冊BeanPostProcessorChecker的作用是在BeanPostProcessor初始化期間有bean被建立了就會列印日誌
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    // 和上面BeanFactoryPostProcessor執行的過程非常相似,同樣是按照PriorityOrdered --> Ordered --> 其他的順序進行註冊,區別是這裡最後加了MergedBeanDefinitionPostProcessor型別的BeanPostProcessor的註冊,並且這裡不會執行相關方法,BeanPostProcessor的相關方法在bean建立時才會執行。這裡看起來有重複註冊的問題,不過beanFactory.addBeanPostProcessor是先移除在新增,所以不會重複
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    sortPostProcessors(beanFactory, internalPostProcessors);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

AbstractBeanFactory:

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    this.beanPostProcessors.remove(beanPostProcessor); // 先移除
    this.beanPostProcessors.add(beanPostProcessor); // 再新增
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

下一步是初始化MessageSource,用於國際化處理,關於Spring的國際化處理,有興趣的讀者可以查閱相關資料進行學習,這裡就不做描述了。接下來我們來看應用事件廣播器的初始化:
AbstractApplicationContext:

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);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else { /* 預設事件廣播器 */
        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 + "]");
        }
    }
}

我們以預設事件廣播器SimpleApplicationEventMulticaster為例看一下它是如何廣播事件的:

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();
        if (executor != null) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    /* 通知監聽器 */
                    invokeListener(listener, event);
                }
            });
        }
        else {
            /* 通知監聽器 */
            invokeListener(listener, event);
        }
    }
}

SimpleApplicationEventMulticaster:

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
        try {
            // 將應用事件通知監聽器
            listener.onApplicationEvent(event);
        }
        catch (Throwable err) {
            errorHandler.handleError(err);
        }
    }
    else {
        try {
            // 將應用事件通知監聽器
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            String msg = ex.getMessage();
            if (msg == null || msg.startsWith(event.getClass().getName())) {
                Log logger = LogFactory.getLog(getClass());
                if (logger.isDebugEnabled()) {
                    logger.debug("Non-matching event type for listener: " + listener, ex);
                }
            }
            else {
                throw ex;
            }
        }
    }
}

很簡單,通知監聽器就是呼叫所有監聽器的onApplicationEvent方法將事件傳入,由監聽器自己決定是否處理當前事件,這是一個典型的觀察者模式的實現。而接下來就是監聽器的註冊:
AbstractApplicationContext:

protected void registerListeners() {
    // 編碼方式的監聽器註冊
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    // 配置方式的監聽器註冊
    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);
        }
    }
}

接下來是初始化所有非lazy-init的bean:
AbstractApplicationContext:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化型別轉換器
    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));
    }
    // 如果沒有配置value處理器(例如PropertyPlaceholderConfigurer)則註冊一個預設的value處理器,主要用於處理註解的value
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
    // 初始化實現LoadTimeWeaverAware的bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    // 凍結BeanDefinition,到這裡BeanDefinition就不能再修改了,下面就要初始化了
    beanFactory.freezeConfiguration();
    /* 初始化非lazy-init的單例bean */
    beanFactory.preInstantiateSingletons();
}

這裡提到的型別轉換器我們可以通過配置ConversionServiceFactoryBean來註冊我們自定義的型別轉換器,就是在這裡初始化的。
DefaultListableBeanFactory:

public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Pre-instantiating singletons in " + this);
    }
    // 獲取所有beanName
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 非abstract、非lazy-init的單例bean
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // FactoryBean的處理
            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 { // 普通bean初始化
                getBean(beanName);
            }
        }
    }
    // 呼叫所有初始化的後的回撥,Spring4.1的新特性,我們的bean實現了SmartInitializingSingleton後,會在初始化後呼叫實現的afterSingletonsInstantiated方法,我們可以在裡面定義一些bean初始化後需要的邏輯
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

bean初始化的過程我們會在後續的文章中進行詳細闡述,下面就是最後一步啦:
AbstractApplicationContext:

protected void finishRefresh() {
    /* 初始化LifecycleProcessor(生命週期處理器) */
    initLifecycleProcessor();
    /* 呼叫onRefresh */
    getLifecycleProcessor().onRefresh();
    // 傳送Spring上下文初始化完成事件
    publishEvent(new ContextRefreshedEvent(this));
    // 註冊MBean
    LiveBeansView.registerApplicationContext(this);
}

AbstractApplicationContext:

protected void initLifecycleProcessor() {
    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 + "]");
        }
    }
    else { /* 預設LifecycleProcessor */
        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 + "]");
        }
    }
}

註冊完LifecycleProcessor接著會呼叫它的onRefresh方法,我們以預設的DefaultLifecycleProcessor為例分析一下它的作用:

public void onRefresh() {
    /* 實現了Lifecycle的bean處理 */
    startBeans(true);
    this.running = true;
}

DefaultLifecycleProcessor:

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

實現了Lifecycle介面的bean,Spring會保證在啟動時呼叫其start方法,在Spring關閉時呼叫其stop方法。到這裡,整個Spring容器就初始化完成了。

相關推薦

Spring原始碼解析ApplicationContext

閱讀須知 Spring原始碼版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 ApplicationContext applicationContext = new ClassPathXmlApplicationContext

spring原始碼解析AOP原理

一、準備工作   在這裡我先簡單記錄下如何實現一個aop: AOP:【動態代理】 指在程式執行期間動態的將某段程式碼切入到指定方法指定位置進行執行的程式設計方式; 1、匯入aop模組;Spring AOP:(spring-aspects) 2、定義一個業務邏輯類(

Spring原始碼解析 Spring Security啟動細節和工作模式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Spring原始碼解析四(容器的功能擴充套件)

容器的功能擴充套件 1、概述 之前的文章中BeanFactory介面以及它的預設實現類XmlBeanFactory為例進行分析,但是Spring中還提供了另一個介面ApplicationContext,用於擴充套件BeanFactory中現有的功能。  ApplicationCon

Spring原始碼解析四(bean載入)

1、概述 已經分析了spring對於xml配置檔案的解析,接下來就是對bean的載入。 getBean的實現 public <T> T getBean(String name, Class<T> requiredType, Object... args) thro

Spring原始碼解析三(自定義標籤的解析

自定義標籤的解析 1、概述:通過前面的文章我們分析了預設標籤的解析,我們先回顧下自定義標籤解析所使用的方法 /** * Parse the elements at the root level in the document: * "import", "alias", "bean".

Spring原始碼解析二(預設標籤的解析

預設標籤解析 概述:本節重點詳細分析預設標籤的解析過程。接上一篇文章講到parseBeanDefinitions(root, delegate); /** * Parse the elements at the root level in the document: * "impor

Spring原始碼解析SpringMVC

1、說在前面的話 ①、在說springmvc之前先說一下與之相關的一些類與介面:ContextLoaderListener與ServletContextListener,ContextLoaderListener實現了ServletContextListener介面。 Context

Spring原始碼解析標籤的解析下篇

正文 上篇文章我們介紹了Spring預設標籤的解析,本文我們來分析一下Spring自定義標籤的解析。上篇文章我們瞭解到Spring的預設標籤目前有4個(import、alias、bean、beans),也就是說除了這4個標籤以外的標籤都是自定義標籤(當然這裡所說的標籤不包括

Spring原始碼解析bean的建立

閱讀須知 Spring原始碼版本:4.3.8 文章中使用/* */註釋的方法會做深入分析 正文 之前我們都是在圍繞 ApplicationContext applicationContext = new ClassPathXmlApplicati

spring原始碼解析IOC容器(一)

  學習優秀框架的原始碼,是提升個人技術水平必不可少的一個環節。如果只是停留在知道怎麼用,但是不懂其中的來龍去脈,在技術的道路上註定走不長遠。最近,學習了一段時間的spring原始碼,現在整理出來,以便日後溫故知新。   IOC容器是spring最核心的模組之一,是整個spring體系的基石,spring其

spring原始碼解析IOC容器(二)------載入和註冊

  上一篇跟蹤了IOC容器對配置檔案的定位,現在我們繼續跟蹤程式碼,看看IOC容器是怎麼載入和註冊配置檔案中的資訊的。開始之前,首先我們先來了解一下IOC容器所使用的資料結構-------BeanDefinition,它是一個上層介面,有很多實現類,分別對應不同的資料載體。我們平時開發的時候,也會定義很多po

spring原始碼解析IOC容器(三)——依賴注入

  上一篇主要是跟蹤了IOC容器對bean標籤進行解析之後存入Map中的過程,這些bean只是以BeanDefinition為載體單純的儲存起來了,並沒有轉換成一個個的物件,今天繼續進行跟蹤,看一看IOC容器是怎樣例項化物件的。   我們都使用過以下程式碼: 1 FileSystemXmlApplicati

Spring原始碼解析ConfigurableApplicationContext

UML圖 介面的作用 從上面的UML圖中,可以看到 ConfigurableApplicationContext 直接繼承了 ApplicationContext, Lifecycle, Closeable 介面,所以 ApplicationContext 是 ApplicationContext 的子類

Spring原始碼解析@Configuration

@Configuration簡介 用於標識一個類為配置類,與xml配置效果類似 用法簡介 public class TestApplication { public static void main(String args[]) { AnnotationConfigApplicati

Spring原始碼解析基礎應用(二)

方法注入 在spring容器中,大部分bean的作用域(scope)是單例(singleton)的,少部分bean的作用域是原型(prototype),如果一個bean的作用域是原型,我們A bean的作用域是原型,B bean中以@Autowired的方式注入A,那麼B在A中依舊是單例。我們可以讓B類實現A

Spring原始碼解析基礎應用(三)

組合Java配置 在XML中,我們可以使用<import/>標籤,在一個XML檔案中引入另一個XML檔案,在Java類中,我們同樣可以在一個配置類中用@Import引入另一個配置類,被引入的配置類中的@Bean也會載入到spring容器。程式碼如下: @Configuration public

Spring原始碼解析BeanFactoryPostProcessor(一)

BeanFactoryPostProcessor 在前面幾個章節,筆者有介紹過BeanFactoryPostProcessor,在spring在解析BeanDefinition之後,正式初始化bean之前,會回撥我們編寫的BeanFactoryPostProcessor介面,介面會傳入beanFactory物

Spring原始碼解析BeanFactoryPostProcessor(二)

上一章,我們介紹了在AnnotationConfigApplicationContext初始化的時候,會建立AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner兩個物件: public class AnnotationConfigAppli

Spring-web原始碼解析Filter-OncePerRequestFilter

轉自:  http://blog.csdn.net/ktlifeng/article/details/50630934 基於4.1.7.RELEASE 我們先看一個filter-mapping的配置