Spring使用xml啓動源碼解析

本文章出處Spring使用xml啓動源碼解析
轉載請說明出處

工程準備

  • 引入Spring最小依賴
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>5.1.8.RELEASE</spring.version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

    </dependencies>
  • applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="org.ting.spring.study.App"/>
</beans>
  • Spring 啓動代碼
package org.ting.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args ){
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        App myBean = (App) app.getBean("myBean");
        System.out.println(myBean);
    }
}

瞭解ClassPathXmlApplicationContext

ClassPathXmlApplicationContext結構圖
這個類基本上都是構造函數
ClassPathXmlApplicationContext方法
可以看出,這個沒有任何業務邏輯代碼,都是通過繼承抽象類擴展功能,主要業務都在父類中。下面我們看下構造方法是怎麼初始化Spring容器的

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

進入this構造方法

public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {
         //設置父容器
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

可以看出,這個纔是ClassPathXmlApplicatonContext實例化方法,設置父容器對象,添加配置文件路徑到容器中,開始啓動容器工作。
super(parent)方法依次調用服務父類AbstractXmlApplicationContextAbstractRefreshableConfigApplicationContextAbstractRefreshableApplicationContextAbstractApplicationContext的構造方法。

    public AbstractApplicationContext(@Nullable ApplicationContext parent) {
        this();
        setParent(parent);
    }
@Override
    public void setParent(@Nullable ApplicationContext parent) {
        this.parent = parent;
        if (parent != null) {
            Environment parentEnvironment = parent.getEnvironment();
            if (parentEnvironment instanceof ConfigurableEnvironment) {
                getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
            }
        }
    }

這個方法主要是向上調用父類構造方法,一直到AbstractApplicationContext對象。參數不爲空的話將父上下文對像Environment設置合併到當前容器中,將兩個容器配置文件合併起來,一般在web環境有使用到。

setConfigLocations

    public void setConfigLocations(@Nullable 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++) {
          //處理路徑,從環境變量中替換佔位符 ${x}
                this.configLocations[i] = resolvePath(locations[i]).trim(); 
            }
        }
        else {
            this.configLocations = null;
        }
    }

將路徑添加到AbstractRefreshableConfigApplicationContextconfigLocations 屬性中,並且出來掉路徑中環境變量佔位符,保證configLocaiton得到是可用地址。

refresh解讀

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //準備刷新上下文對象
            prepareRefresh();

            // 創建Spring Factory對象,清空緩存,解析xml文件轉換成BeanDefinition 保存到緩存中
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //初始化BeanFactory 內部屬性值,添加類型轉換 ,前置處理器
            prepareBeanFactory(beanFactory);

            try {
                // 空方法,讓字類實現查看或者修改beanFacory內部屬性值
                postProcessBeanFactory(beanFactory);

                // 註冊實例化BeanFactoryPostProcessor,並且執行所有類接口方法
                invokeBeanFactoryPostProcessors(beanFactory);

                //註冊所有後置處理器
                registerBeanPostProcessors(beanFactory);

                //初始化messageSource bean
                initMessageSource();

                //初始化組播器
                initApplicationEventMulticaster();

                // 空方法,讓字類自行初始化特別bean
                onRefresh();

                // 初始化所有事件監聽器,加入組播器中,廣播事件
                registerListeners();

                //啓動所有非延遲單例bean 
                finishBeanFactoryInitialization(beanFactory);

                // 完成applicationContext初始化工作
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // 銷燬已經創建成功bean
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                //清空所有類型註解掃描,反射等元數據集合
                resetCommonCaches();
            }
        }
    }

下面我們一個個方法解析

prepareRefresh

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

        if (logger.isDebugEnabled()) {
            if (logger.isTraceEnabled()) {
                logger.trace("Refreshing " + this);
            }
            else {
                logger.debug("Refreshing " + getDisplayName());
            }
        }

        // 初始化PropertySource ,默認不做任何處理,讓子類實現
        initPropertySources();

        // Validate that all properties marked as required are resolvable:
        // see ConfigurablePropertyResolver#setRequiredProperties
        getEnvironment().validateRequiredProperties();

        // Store pre-refresh ApplicationListeners...
        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);
        }

        // Allow for the collection of early ApplicationEvents,
        // to be published once the multicaster is available...
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

設置啓動時間,將關閉標記設置false,活動開關設置true,initPropertySources(),本身是一個空方法,由子類自行去實現,讓子類在容器創建之前修改ConfigurableEnvironmentPropertySources對象屬性。PropertySourcesname/value鍵值對的封裝接口,主要用來裝配配置變量。雖然ClassPathXmlApplicatonContext和他的父類都沒有實現這個方法,在Spring MVC中, GenericWebApplicationContext實現initPropertySources方法,將servletContext配置變量合併到ProertySources中。接着看getEnvironment().validateRequiredProperties()這個方法實現在

validateRequiredProperties

    @Override
    public void validateRequiredProperties() {
        MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
        for (String key : this.requiredProperties) {
            if (this.getProperty(key) == null) {
                ex.addMissingRequiredProperty(key);
            }
        }
        if (!ex.getMissingRequiredProperties().isEmpty()) {
            throw ex;
        }
    }

主要校驗ProertySources中key value,是否有不對應的情況。其實這個主要校驗上一個initPropertySources()方法安全措施來的。比如老爸放手讓自己兒子去做一件事,自己完全不干預,但是他會偷偷去查看事件做得怎麼樣?如果做不不行,狠狠打兒子一頓。

ConfigurableListableBeanFactory初始化

這部分應該是整個代碼解析最核心的功能了,這個類就是我們經常說的Spring容器,Spring工廠的實現DefaultListableBeanFactory。主要負責bean註冊實例化,bean查找,bean別名,bean銷燬。這裏實例化這個對象,也開始說明Spring生命週期正式開始。下面是 DefaultListableBeanFactory的繼承關係
DefaultListableBeanFactory
查看obtainFreshBeanFactory方法具體內容

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        return getBeanFactory();
    }

refreshBeanFactory主要是清除ConfigurableListableBeanFactory bean緩存,重新實例化。

refreshBeanFactory

這個方法在AbstractRefreshableApplicationContext

protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) { //判斷ConfigurableListableBeanFactory 是否已經創建了 
            destroyBeans();
            closeBeanFactory();
        }
        try {
                        //使用構造函數實例化new DefaultListableBeanFactory(parent)
            DefaultListableBeanFactory beanFactory = createBeanFactory(); 
            beanFactory.setSerializationId(getId());
                //Spring 工廠自定義設置,是否運行已經註冊bean被相同beanName覆蓋,默認是true,設置是否允許bean之間的循環引用 - 並嘗試自動解決它默認也是true
            customizeBeanFactory(beanFactory);
            //開始解析xml配置文件,註冊BeanDefinition,下面具體分析
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

先判斷ConfigurableListableBeanFactory對象是否已經創建成功了,如果已經存在了,執行銷燬Spring容器內已經註冊bean銷燬,重新實例化ConfigurableListableBeanFactory對象,設置id,設置beanFactory bean重名,依賴解決方式。開始加載xml配置文件,註冊BeanDefinition,將已經實例化BeanFactory指引再指向this.beanFactory。

主要看下destroyBeans()

protected void destroyBeans() {
        getBeanFactory().destroySingletons();
    }

調用了ConfigurableListableBeanFactory的destroySingletons方法,接口的實現類是DefaultListableBeanFactory

@Override
    public void destroySingletons() {
        super.destroySingletons();
        updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
        clearByTypeCache();
    }
destroySingletons

super.destroySingletons()調用了DefaultSingletonBeanRegistrydestroySingletons方法

public void destroySingletons() {
        if (logger.isTraceEnabled()) {
            logger.trace("Destroying singletons in " + this);
        }
        synchronized (this.singletonObjects) {
            this.singletonsCurrentlyInDestruction = true;
        }

        String[] disposableBeanNames;
        synchronized (this.disposableBeans) { //將map key 轉化成string 數組
            disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
        }
        for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
            destroySingleton(disposableBeanNames[i]);
        }

        this.containedBeanMap.clear();
        this.dependentBeanMap.clear();
        this.dependenciesForBeanMap.clear();

        clearSingletonCache();
    }
destroySingleton
public void destroySingleton(String beanName) {
        // Remove a registered singleton of the given name, if any.
        removeSingleton(beanName);

        // Destroy the corresponding DisposableBean instance.
        DisposableBean disposableBean;
        synchronized (this.disposableBeans) {
            disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
        }
        destroyBean(beanName, disposableBean);
    }

查看removeSingleton方法

protected void removeSingleton(String beanName) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.remove(beanName);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.remove(beanName);
        }
    }

這幾個分別就是內部容器來的,看下主要用途

    /**緩存單例bean對象 : beanName 對應 bean對象 */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /**緩存單例工廠: beanName 對應 bean工廠實體. */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** 緩存bean早期對象,主要是bean註冊的實體依賴對象: beanName 對應 實體對象 */
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    /**已經成功註冊beanName,按住註冊順序保存 */
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
destroyBean
    protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
        // Trigger destruction of dependent beans first...
        Set<String> dependencies;
        synchronized (this.dependentBeanMap) {
            // Within full synchronization in order to guarantee a disconnected Set
            dependencies = this.dependentBeanMap.remove(beanName);
        }
        if (dependencies != null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
            }
            for (String dependentBeanName : dependencies) {
                destroySingleton(dependentBeanName);
            }
        }

        // Actually destroy the bean now...
        if (bean != null) {
            try {
                bean.destroy();
            }
            catch (Throwable ex) {
                if (logger.isInfoEnabled()) {
                    logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
                }
            }
        }

        // Trigger destruction of contained beans...
        Set<String> containedBeans;
        synchronized (this.containedBeanMap) {
            // Within full synchronization in order to guarantee a disconnected Set
            containedBeans = this.containedBeanMap.remove(beanName);
        }
        if (containedBeans != null) {
            for (String containedBeanName : containedBeans) {
                destroySingleton(containedBeanName);
            }
        }

在刪除DisposableBean實例的時候,獲取bean下依賴實例,逐個移除。最後將Spring容器依賴實體逐個移除。接着看closeBeanFactory()辦法

loadBeanDefinitions 解析

    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
         //xml  文件約束校驗
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // Allow a subclass to provide custom initialization of the reader,
        // 設置xml校驗方式
        initBeanDefinitionReader(beanDefinitionReader);
                //開始解析xml轉化BeanDefinition
        loadBeanDefinitions(beanDefinitionReader);
    }

實例化XmlBeanDefinitionReader將資源文件xml解析成BeanDefinition,將Spring上下文對象賦值給對象屬性。loadBeanDefinitions會將xml文件轉化成Document對象,由於這部分太過繁瑣,需要根據文件名獲取ResouceLoader,再獲取到文件流對象,解析xml成Document,覺得省略這些代碼解析,主要放在Document如何轉化成BeanDefinition,在DefaultBeanDefinitionDocumentReader實現。

doRegisterBeanDefinitions
    protected void doRegisterBeanDefinitions(Element root) {
        // Any nested <beans> elements will cause recursion in this method. In
        // order to propagate and preserve <beans> default-* attributes correctly,
        // keep track of the current (parent) delegate, which may be null. Create
        // the new (child) delegate with a reference to the parent for fallback purposes,
        // then ultimately reset this.delegate back to its original (parent) reference.
        // this behavior emulates a stack of delegates without actually necessitating one.
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(getReaderContext(), root, parent);

        if (this.delegate.isDefaultNamespace(root)) {
            String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
                    //判斷文件profile屬性,轉化成array
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                // We cannot use Profiles.of(...) since profile expressions are not supported
                // in XML config. See SPR-12458 for details.
                if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                                "] not matching: " + getReaderContext().getResource());
                    }
                    return;
                }
            }
        }
        //運行自定義實現類 預處理xml文件,空方法,讓子類實現。
        preProcessXml(root);
        parseBeanDefinitions(root, this.delegate);
       //運行自定義自主實心方法,修改xml屬性,空方法。  
        postProcessXml(root);

        this.delegate = parent;
    }

BeanDefinitionParserDelegate主要是解析Document命名空間,標籤元素,屬性,將xml標籤轉化成對象。

prseBeanDefinitions
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                                              //註冊BeanDefinition
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }

循環遍歷beans的子標籤,符合"import", "alias", "bean"命名空間,進入標籤解析環節

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }

主要看下bean標籤解析

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

這個方法將xml解析返回 BeanDefinition對象,如果對象不爲空,繼續解析元素的自定義屬性,並將元素自定義屬性設置給剛剛創建BeanDefiniton對象,最後廣播註冊BeanDefinition對象。關於如何生成BeanDefiniton對象,這個方法我不具體深入瞭解了,畢竟裏面篇幅很多的,以後會專門出一個章節去說明。

prepareBeanFactory 方法解析

prepareBeanFactory方法主要是配置BeanFactory 類加載器,Spring el表達式實現,bean前置處理器等等的屬性設置,主要邏輯詳看下面的代碼

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
    //設置工廠類加載器    beanFactory.setBeanClassLoader(getClassLoader());
        //設置Spring el表達式實現 
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
       //添加屬性轉化器
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
        /*
         * 添加後置處理器實現, 如果實現了相應的 Aware 接口,則注入對應的資源
         * 1. EnvironmentAware
         * 2. EmbeddedValueResolverAware
         * 3. ResourceLoaderAware
         * 4. ApplicationEventPublisherAware
         * 5. MessageSourceAware
         * 6. ApplicationContextAware
         */
        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);

              //將Spring 內部對象緩存起來,註冊到容器內部。
        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));

        // 判斷存在AOP bean name 則註冊aop前置處理器
        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()));
        }

        // 註冊 默認environment beans.
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
                //向Spring容器註冊bean
            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());0

        }
    }

BeanPostProcessor

addBeanPostProcessor方法主要添加BeanPostProcessor接口實現類,Bean 的後置處理器,主要是在 bean 初始化前後進行一些處理工作,spring bean 創建委派給個大後置處理器創建。

public interface BeanPostProcessor {

    /**
     * bean 在創建之前,對bean進行處理,將處理過實體返回給BeanFactory容器
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * bean創建之後,對bean進行處理,相當於給已經創建的進行功能加強
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}

ApplicationContextAwareProcessor

    @Override
    @Nullable
    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((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    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是否實現了EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware.ApplicationContextAware接口,如果是,直接執行接口方法,將Spring工廠方法注入屬性中。這個也解析了上面設置registerResolvableDependency依賴注入忽略。

postProcessBeanFactory

postProcessBeanFactory方法中沒有任何實現,主要是允許子類在Spring工廠還沒有初始化bean之前,添加一些特殊bean進入到容器中,比如添加BeanPostProcessors接口實現類。這時候Spring 已經解析完xml,還需要想添加一些bean到容器中,這時候就可以實現這個方法。

invokeBeanFactoryPostProcessors

BeanFactoryPostProcessors接口跟BeanPostProcessor類似,可以用於bean的定義進行處理,也可以在bean初始化之前修改bean元數據。可以配置多個BeanFactoryPostProcessor,使用Order接口來控制執行順序。源碼展示

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        //執行BeanFactoryPostProcessors  ,從容器中已經實例化對象中執行方法
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {//判斷是否需要AOP支持,註冊AOP前置處理器
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

invokeBeanFactoryPostProcessors

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

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {  //強制類型 BeanDefinitionRegistryPostProcessor接口需要用到
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
              //遍歷所有BeanFactoryPostProcessor,按照BeanFactoryPostProcessor類型和BeanDefinitionRegistryPostProcessor類型分別放入不用容器中,
             //並且執行BeanDefinitionRegistryPostProcessor接口方法。
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry); //執行接口方法,參考或者修改bean 元數據
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
              //獲取工廠中所以BeanDefinitionRegistryPostProcessor類型 bean
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
                //執行集合中所有BeanDefinitionRegistryPostProcessors 接口方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            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);
                }
            }
                   //根據order接口排序集合中的順序     
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 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)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

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

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            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);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }

    

看起來代碼挺多,其實很簡單的邏輯。

  1. 遍歷循環所有BeanFactoryPostProcessor集合,首先取出BeanDefinitionRegistryPostProcessor,並且執行接口方法,再放入registryProcessors容器中。
  2. BeanFactory 中獲取所有BeanDefinitionRegistryPostProcessor類型的bean name 數組,遍歷循環數據,判斷是否有PriorityOrdered接口,加入容器中,並且根據接口重新排序後,遍歷容器所有類,執行接口方法,加入registryProcessors容器中。
  3. 在獲取容器所有BeanDefinitionRegistryPostProcessor類型的bean name 數組,循環遍歷bean name 取出實現Ordered接口,按照Orderd順序排序集合,依次執行接口方法,加入放入registryProcessors容器中.
  4. 將剩下所有BeanDefinitionRegistryPostProcessor,加入registryProcessors容器中。執行registryProcessors容器中所有BeanFactoryPostProcessor的接口方法。
  5. BeanFactoryPostProcessor也是按照上面的思路,先過濾排序執行接口方法。

看到這裏我有一個疑問,這些接口對象怎麼產生的?Spring 工廠並沒有開始實例化對象,這時候Spring只進行到將xml轉化成beanDefinition這個對象,不可能從Spring 工廠獲取出來的。

BeanFactoryPostProcessor實例化過程

實例化bean 的方法主要在AbstractBeanFactory

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
              // 取出&提取對應beanName 
        final String beanName = transformedBeanName(name);
        Object bean;

        // 在緩存中獲取對象
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
                 //判斷緩存中對象是否是正確的bean實例化,如果是FactoryBean接口對象,調用接口方法獲取到bean實例  
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // 如果beanName 是prototpe或者scope類型,並且正在創建中,直接拋出異常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 嘗試在父容器獲取
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 沒有找到,嘗試修改beanName名稱,重新來過
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }
              //如果只是做類型檢查,不進行實例化,這將bean加入創建記錄中
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {  
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                        //判斷BeanDefinition 類型不是抽象類
                checkMergedBeanDefinition(mbd, beanName, args);

                // 獲取bean 元數據所有依賴bean 
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) { //檢查是否存在依賴關係
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //相互添加依賴和被依賴的關聯
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep); //實例化創建依賴bean
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 創建單例對象
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //具體創建bean方法,由子類 AbstractAutowireCapableBeanFactory實現
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                                          //添加創建記錄
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                                         //刪除記錄
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // 類型檢查  得到bean可能是String類型,但是需要轉化成Integer類型
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                          //使用類型轉化器
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

這個就是Spring 創建bean具體流程,但是任然還有很多細節沒有表達出來,看了這麼多源碼,都知道一個方法不可能放得下這麼多邏輯的。以後有機會我入深入每個方法再具體講解的。主要總結下Spring 創建bean整體路程。

  1. 處理beanName,去除FactoryBean的修飾符,也就是"&name" 轉化成"name"。將alias name 轉化成真正beanName。
  2. 如果是否是單例,嘗試從緩存中加載bean。再處理緩存中bean,在緩存中記錄的只是最原始bean,並一定是我們最終想要的bean,需要getObjectForBeanInstance來完成這個工作。
  3. 原型依賴檢查
  4. 嘗試從父容器中獲取bean,如果父容器不爲空並且包含beanName情況下。
  5. 獲取beanName下所有的依賴bean,並且實例化所有的依賴bean
  6. 根據對象scope 分別實例化bean。
  7. 實例化結束後,將對象轉化成requiredType 給定類型。

registerBeanPostProcessors

註冊所有BeanPostProcessor後置處理類,這裏只是註冊,不會執行任何接口方法。具體流程跟上面BeanFactoryPostProcessor非常相似。在PostProcessorRegistrationDelegate看下具體代碼邏輯,注意與上面代碼相似地方。

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
           //根據類型獲取所有BeanPostProcessor beanName 
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 註冊 BeanPostProcessorChecker 只是一個info 日誌信息打印類
        // 當一個bean 正在被BeanPostProcessor 創建時就會打印信息
        // 這個bean不能是BeanPostProcessor類型
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 使用PriorityOrdered 排序bean 執行順序
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
               //MergedBeanDefinitionPostProcessor 接口容器
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
              //使用Ordered 接口排序bean 執行順序
        List<String> orderedPostProcessorNames = new ArrayList<>();
              // 默認順序排序
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        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);
            }
        }

        //首先註冊PriorityOrdered 優先排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
               //只是註冊處理器,不調用方法
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 接着註冊Ordered 類型 優先排序
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 註冊所有常規 BeanPostProcessors.
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // 最後註冊 MergedBeanDefinitionPostProcessor 類型
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // 註冊ApplicationListener 後置處理器
        // 添加到所有處理器鏈後面
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

BeanPostProcessor註冊流程跟上面BeanFactoryPostProcessor非常相似啊。

  1. 根據BeanPostProcessor獲取所有後置處理器beanName
  2. 根據beanName數組長度創建BeanPostProcessorChecker對象,並註冊到容器中。
  3. 根據PriorityOrdered,MergedBeanDefinitionPostProcessor,Ordered,等類型分別創建不同處理器容器
  4. 根據不同類型排序註冊處理器

initMessageSource

初始化信息資源類,Spring內部國際化支持。邏輯非常簡單,先判斷容器內是否有messageSource,直接註冊bean,否則Spring內部註冊DelegatingMessageSource。代碼我就不放出來了,有興趣同學自行去查看。

initApplicationEventMulticaster

初始化ApplicationEventMulticaster事件組播器,主要判斷用戶是否自定義了事件組播器,直接使用用戶定義的組播器。如果沒有用戶自定義組播器,默認使用SimpleApplicationEventMulticaster,代碼略...

onRefresh

初始化其他特殊bean,由子類自行實現。這裏又是使用了模板方法設計模式,讓使用者可以擴展新功能。

registerListeners

註冊所有實現ApplicationListeners接口的監聽器,添加到上面剛剛初始化組播器中。獲取所有事件集合,發佈到組播器中,組播器再廣播到監聽指定事件的監聽器中。

    protected void registerListeners() {
        // Register statically specified listeners first.
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

finishBeanFactoryInitialization

這個方法就是我們解析Spring IOC核心了,初始化所有Spring bean,看這麼多代碼,終於到了我們最想了解部分了,直接上代碼

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化conversion service 用於類型轉化
        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));
        }

        //如果沒有後置處理器,默認就支持嵌入值解析器
        // 例如PropertyPlaceholderConfigurer bean之前註冊的任何一個
        // 主要用於配置佔位符解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 在所有bean初始化之前初始化所有AOP 代理對象
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 取消臨時類加載器,關閉類型查找        beanFactory.setTempClassLoader(null);

        //凍結所有beanDefinition 特性
        beanFactory.freezeConfiguration();

        // 初始化非延遲單例bean (創建所有bean)
        beanFactory.preInstantiateSingletons();
    }
  1. 判斷容器內是否有conversionService,並且類型必須是 ConversionService,則實例化bean。ConversionService接口也是個類型轉換器。
  2. 判斷容器內是否有StringValueResolver類型bean,沒有手動註冊一個。
  3. 初始化所有AOP 通知類型。

4.凍結所有bean元數據特性,不允許任何修改。

  1. 實例化所有非延遲單例bean

preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }

        // 遍歷所有beanDefinitionNames,copy 到信息list中
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // 實例化所有非延遲bean 
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {// 判斷FactoryBean 接口類型bean 
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }

        // 執行bean中實現SmartInitializingSingleton接口,執行接口方法,用與單例bean 初始化成功後執行
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

finishRefresh

    protected void finishRefresh() {
        // 清空容器中Resource緩存
        clearResourceCaches();

        // 初始化LifecycleProcessor,註冊到Spring容器中
        initLifecycleProcessor();

        //調用上面剛剛註冊LifecycleProcessor onRefresh方法
        getLifecycleProcessor().onRefresh();

        // 發佈ApplicationContext 完成初始化事件
        publishEvent(new ContextRefreshedEvent(this));

        // 如果配置文件中存在spring.liveBeansView.mbeanDomain 初始化LiveBeansView 註冊到容器中
        LiveBeansView.registerApplicationContext(this);
    }

到這裏說明Spring 創建bean過程差不多完成了,但是還有很多細節沒有展示出來,因爲篇幅實在太多了。可以看出我前面講得還是比較詳細的,到了後面簡略一些方法解析,篇幅實在太長了。如果有哪裏說錯了,或者講得不好,請指出來,大家一起學習討論下。

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