Spring IoC源碼解析之getBean

1、實例化全部的非懶加載的單實例Bean

  從org.springframework.context.support.AbstractApplicationContext#refresh方法開發,進入到實例化全部的非懶加載的單實例Bean的finishBeanFactoryInitialization(beanFactory)的方法:html

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 爲Bean工廠設置類型轉化器
        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));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        //凍結全部的Bean定義 , 至此註冊的Bean定義將不被修改或任何進一步的處理
        beanFactory.freezeConfiguration();

        //實例化剩下的單實例Bean
        beanFactory.preInstantiateSingletons();
    }

  進入實例化剩下的單實例Bean的beanFactory.preInstantiateSingletons()的方法:spring

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

        //獲取咱們容器中全部Bean定義的名稱
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        //循環咱們全部的bean定義名稱
        for (String beanName : beanNames) {
            //合併咱們的bean定義
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //根據bean定義判斷是否是抽象的 && 不是單例的 && 不是懶加載的
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //是否FactoryBean
                if (isFactoryBean(beanName)) {
                    //是 給beanName+前綴 & 符號
                    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());
                        }
                        //調用真正的getBean
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {//非工廠Bean就是普通的bean
                    getBean(beanName);
                }
            }
        }

        //獲取全部的bean的名稱 至此全部的單實例的bean已經加入到單實例Bean的緩存池中,所謂的單實例緩存池實際上就是一個ConcurrentHashMap
        for (String beanName : beanNames) {
            //從單例緩存池中獲取全部的對象
            Object singletonInstance = getSingleton(beanName);
            //判斷當前的bean是否實現了SmartInitializingSingleton接口
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    //觸發實例化以後的方法afterSingletonsInstantiated
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

  前面多個地方涉及到getBean,接下來就分析下getBean(很重要緩存

2、getBean流程

  進入getBean(beanName)的方法:app

@Override
    public Object getBean(String name) throws BeansException {
        //真正的獲取Bean的邏輯
        return doGetBean(name, null, null, false);
    }

  該方法啥沒幹,又交給了幹活的doGetBean(name, null, null, false)方法:ide

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        //在這裏傳入進來的name多是別名、也有多是工廠beanName,因此在這裏須要轉換
        final String beanName = transformedBeanName(name);
        Object bean;

        //先嚐試去緩存中獲取對象
        Object sharedInstance = getSingleton(beanName);

        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            /**
             * 若是sharedInstance是普通的單例bean,下面的方法會直接返回。但若是
             * sharedInstance是FactoryBean類型的,則需調用getObject工廠方法獲取真正的
             * bean實例。若是用戶想獲取 FactoryBean 自己,這裏也不會作特別的處理,直接返回
             * 便可。畢竟 FactoryBean 的實現類自己也是一種 bean,只不過具備一點特殊的功能而已。
             */
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {

            //Spring只能解決單例對象的setter注入的循環依賴,不能解決構造器注入,也不能解決多實例的循環依賴
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            //判斷是否有父工廠
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //若存在父工廠,切當前的bean工廠不存在當前的bean定義,那麼bean定義是存在於父beanFactory中
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                //獲取bean的原始名稱
                String nameToLookup = originalBeanName(name);
                //若爲AbstractBeanFactory類型,委託父類處理
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // 委託給構造函數getBean()處理
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // 沒有args,委託給標準的getBean()處理
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            /**
             * 方法參數typeCheckOnly ,是用來判斷調用getBean(...) 方法時,表示是否爲僅僅進行類型檢查獲取Bean對象
             * 若是不是僅僅作類型檢查,而是建立Bean對象,則須要調用markBeanAsCreated(String beanName) 方法,進行記錄
             */
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //從容器中獲取beanName相應的GenericBeanDefinition對象,並將其轉換爲RootBeanDefinition對象
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //檢查當前建立的bean定義是否是抽象的bean定義
                checkMergedBeanDefinition(mbd, beanName, args);

                //處理dependsOn的依賴(這個不是咱們所謂的循環依賴 而是bean建立先後的依賴)
                //依賴bean的名稱
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        //beanName是當前正在建立的bean,dep是正在建立的bean的依賴的bean的名稱
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //保存的是依賴beanName之間的映射關係:依賴beanName -> beanName的集合
                        registerDependentBean(dep, beanName);
                        try {
                            //獲取dependsOn的bean
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                //是單例則建立單例Bean
                if (mbd.isSingleton()) {
                    //把beanName和一個singletonFactory匿名內部類傳入用於回調
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            //建立bean的邏輯
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            //建立bean的過程當中發生異常,須要銷燬關於當前bean的全部信息
                            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;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        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.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

  第一步:先嚐試去緩存中獲取對象

  Object sharedInstance = getSingleton(beanName),因爲第一次確定爲空:函數

public Object getSingleton(String beanName) {
        //在這裏系統通常是容許早期對象引用的allowEarlyReference經過這個參數能夠控制解決循環依賴
        return getSingleton(beanName, true);
    }

  進入到getSingleton(beanName, true)方法,這裏涉及到Spring的三級緩存,用它來解決循環依賴:post

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        /**
         * 第一步:咱們嘗試去一級緩存(單例緩存池中去獲取對象,通常狀況從該map中獲取的對象是直接可使用的)
         * Spring IoC容器初始化加載單實例bean的時候第一次進來的時候 該map中通常返回空
         */
        Object singletonObject = this.singletonObjects.get(beanName);
        /**
         * 若在第一級緩存中沒有獲取到對象,而且singletonsCurrentlyInCreation正在建立的單實例的list包含該beanName
         * Spring IoC容器初始化加載單實例bean的時候第一次進來的時候 該list中通常返回空,可是循環依賴的時候能夠知足該條件
         */
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                /**
                 * 嘗試去二級緩存中獲取對象(二級緩存中的對象是一個早期對象)
                 * 何爲早期對象:就是bean剛剛調用了構造方法,還沒給bean的屬性進行賦值的對象就是早期對象
                 */
                singletonObject = this.earlySingletonObjects.get(beanName);
                /**
                 * 二級緩存中也沒有獲取到對象,allowEarlyReference爲true(參數是有上一個方法傳遞進來的true)
                 */
                if (singletonObject == null && allowEarlyReference) {
                    /**
                     * 直接從三級緩存中獲取ObjectFactory對象 這個對接就是用來解決循環依賴的關鍵所在
                     * 在getBean的過程當中,當bean調用了構造方法的時候,把早期對象包裹成一個ObjectFactory暴露到三級緩存中
                     */
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    //從三級緩存中獲取到對象不爲空
                    if (singletonFactory != null) {
                        /**
                         * 在這裏經過暴露的ObjectFactory包裝對象中,經過調用他的getObject()來獲取咱們的早期對象
                         * 在這個環節中會調用到 getEarlyBeanReference()來進行後置處理
                         */
                        singletonObject = singletonFactory.getObject();
                        //把早期對象放置在二級緩存,
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //ObjectFactory 包裝對象從三級緩存中刪除掉
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

  第二步:走else邏輯

  Spring只能解決單例對象的setter注入的循環依賴,不能解決構造器注入,也不能解決多實例的循環依賴,因此會拋Bean當前正在建立的異常,接着判斷是否有父工廠,有就調用父工廠的getBean,若是不是僅僅作類型檢查,而是建立Bean對象,則須要調用markBeanAsCreated方法進行標識ui

  合併Bean定義信息

  ① 接着調用getMergedLocalBeanDefinition(beanName)進行Bean定義的合併方法以下:this

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        // 快速從緩存中獲取,若是不爲空,則直接返回
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null) {
            return mbd;
        }
        //獲取 RootBeanDefinition 對象。若獲取的 BeanDefinition 爲子 BeanDefinition,則須要合併父類的相關屬性.
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }

  ② 進入到getMergedBeanDefinition(beanName, getBeanDefinition(beanName))方法:spa

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
            throws BeanDefinitionStoreException {
        //調用重載的方法
        return getMergedBeanDefinition(beanName, bd, null);
    }

  ③ 進入到getMergedBeanDefinition(beanName, bd, null)的方法:

protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {

        //加鎖
        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;

            // Check with full lock now in order to enforce the same merged instance.
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }

            if (mbd == null) {
                //bd.getParentName() == null,代表無父配置,這時直接將當前的BeanDefinition升級爲RootBeanDefinition
                if (bd.getParentName() == null) {
                    //直接把原始的bean定義升級爲RootBeanDefinition
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        //包裹爲RootBeanDefinition
                        mbd = new RootBeanDefinition(bd);
                    }
                }
                //有父定義
                else {
                    BeanDefinition pbd;
                    try {
                        /*
                         * 判斷父類beanName與子類beanName名稱是否相同。若相同,則父類bean必定
                         * 在父容器中。緣由也很簡單,容器底層是用Map緩存<beanName, bean> 鍵值對
                         * 的。同一個容器下,使用同一個 beanName 映射兩個bean實例顯然是不合適的
                         */
                        String parentBeanName = transformedBeanName(bd.getParentName());
                        if (!beanName.equals(parentBeanName)) {
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            /*
                             * 這裏再次調用getMergedBeanDefinition,只不過參數值變爲了
                             * parentBeanName,用於合併父BeanDefinition 和爺爺輩的
                             * BeanDefinition。若是爺爺輩的BeanDefinition仍有父
                             * BeanDefinition,則繼續合併
                             */
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }
                            else {
                                throw new NoSuchBeanDefinitionException(parentBeanName,
                                        "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                        "': cannot be resolved without an AbstractBeanFactory parent");
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                    }
                    //以父BeanDefinition的配置信息爲基本建立RootBeanDefinition
                    mbd = new RootBeanDefinition(pbd);
                    //用子BeanDefinition中的屬性覆蓋父BeanDefinition中的屬性
                    mbd.overrideFrom(bd);
                }

                // 若是用戶未配置scope屬性,則默認將該屬性配置爲singleton
                if (!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
                }

                // A bean contained in a non-singleton bean cannot be a singleton itself.
                // Let's correct this on the fly here, since this might be the result of
                // parent-child merging for the outer bean, in which case the original inner bean
                // definition will not have inherited the merged outer bean's singleton status.
                if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    mbd.setScope(containingBd.getScope());
                }

                //緩存合併後的BeanDefinition
                if (containingBd == null && isCacheBeanMetadata()) {
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }

            return mbd;
        }
    }

  ④ 而後檢查當前建立的bean定義是否是抽象的bean定義,checkMergedBeanDefinition(mbd, beanName, args)方法:

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
            throws BeanDefinitionStoreException {

        //抽象的bean定義是不可以被實例化的
        if (mbd.isAbstract()) {
            throw new BeanIsAbstractException(beanName);
        }
    }

  處理dependsOn的依賴(這個不是咱們所謂的循環依賴 而是bean建立先後的依賴)

  ① 進入到isDependent(beanName, dependentBeanName, null)的方法:

private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
        //alreadySeen已經檢測的依賴bean
        if (alreadySeen != null && alreadySeen.contains(beanName)) {
            return false;
        }
        //獲取原始beanName
        String canonicalName = canonicalName(beanName);
        //獲取建立當前bean所依賴的bean的名稱集合
        Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
        //不依賴任何前置Bean直接返回
        if (dependentBeans == null) {
            return false;
        }
        //存在,則證實存在已經註冊的依賴
        if (dependentBeans.contains(dependentBeanName)) {
            return true;
        }
        //遞歸檢測依賴
        for (String transitiveDependency : dependentBeans) {
            if (alreadySeen == null) {
                alreadySeen = new HashSet<>();
            }
            //添加到alreadySeen 中
            alreadySeen.add(beanName);
            //遞歸檢查依賴
            if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                return true;
            }
        }
        return false;
    }

  ② 進入到保存的是依賴beanName之間的映射關係:依賴beanName -> beanName的集合registerDependentBean(dep, beanName)的方法:

public void registerDependentBean(String beanName, String dependentBeanName) {
        //獲取原始的beanName
        String canonicalName = canonicalName(beanName);

        // 添加 <canonicalName, dependentBeanName> 到 dependentBeanMap 中
        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                    this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
            }
        }

        // 添加 <dependentBeanName, canonicalName> 到 dependenciesForBeanMap 中
        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean =
                    this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
            dependenciesForBean.add(canonicalName);
        }
    }

  ③ 而後到獲取dependsOn的Bean的getBean(dep),就獲取到了dependsOn的Bean了;

  處理單實例Bean

  ① 把beanName和一個singletonFactory匿名內部類傳入用於回調的getSingleton方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        //加鎖
        synchronized (this.singletonObjects) {
            //嘗試從單例緩存池中獲取對象
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                /**
                 * 標記當前的bean立刻就要被建立了
                 * singletonsCurrentlyInCreation 在這裏會把beanName加入進來,若第二次循環依賴(構造器注入會拋出異常)
                 */
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    //建立bean這個過程實際上是調用 createBean() 方法
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    //回調咱們singletonObjects的get方法,進行正在的建立bean的邏輯
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //後置處理主要作的事情就是把singletonsCurrentlyInCreation標記正在建立的bean從集合中移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //加入緩存中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

   第一:先到單例緩存池中獲取對象獲取,有就返回沒有就繼續往下

   第二:調用標記當前的bean立刻就要被建立了beforeSingletonCreation(beanName)方法:

protected void beforeSingletonCreation(String beanName) {
        //若singletonsCurrentlyInCreation沒有 則添加成功
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    

  第三:建立Bean的singletonFactory.getObject()實際上是調用createBean()方法:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

  真正的建立咱們的bean的實例對象的doCreateBean(beanName, mbdToUse, args)的方法:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        //BeanWrapper是對Bean的包裝,其接口中所定義的功能很簡單包括設置獲取被包裝的對象,獲取被包裝bean的屬性描述器
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            //從沒有完成的FactoryBean中移除
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //使用合適的實例化策略來建立新的實例:工廠方法、構造函數自動注入、簡單初始化 比較複雜也很重要
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //從beanWrapper中獲取咱們的早期對象
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    //進行後置處理@AutoWired的註解的預解析
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        /**
         * 該對象進行判斷是否可以暴露早期對象的條件
         * 單實例 this.allowCircularReferences 默認爲true
         * isSingletonCurrentlyInCreation(表示當前的bean對象正在建立singletonsCurrentlyInCreation包含當前正在建立的bean)
         */
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        //上述條件知足,容許中期暴露對象
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            //把咱們的早期對象包裝成一個singletonFactory對象 該對象提供了一個getObject方法,該方法內部調用getEarlyBeanReference方法
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //給咱們的屬性進行賦值(調用set方法進行賦值)
            populateBean(beanName, mbd, instanceWrapper);
            //進行對象初始化操做(在這裏可能生成代理對象)
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        //容許早期對象的引用
        if (earlySingletonExposure) {
            /**
             * 去緩存中獲取到咱們的對象 因爲傳遞的allowEarlyReference 是false 要求只能在一級二級緩存中去獲取
             * 正常普通的bean(不存在循環依賴的bean) 建立的過程當中,壓根不會把三級緩存提高到二級緩存中
             */
            Object earlySingletonReference = getSingleton(beanName, false);
            //可以獲取到
            if (earlySingletonReference != null) {
                //通過後置處理的bean和早期的bean引用還相等的話(表示當前的bean沒有被代理過)
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                //處理依賴的bean
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            //註冊銷燬的bean的銷燬接口
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

  ① 實例化:使用合適的實例化策略來建立新的實例:工廠方法、構造函數自動注入、簡單初始化的createBeanInstance方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //從bean定義中解析出當前bean的class對象
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        //檢測類的訪問權限。默認狀況下,對於非 public 的類,是容許訪問的。若禁止訪問,這裏會拋出異常
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }

        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        //工廠方法,咱們經過配置類來進行配置的話 採用的就是工廠方法
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        //判斷當前構造函數是否被解析過
        boolean resolved = false;
        //有沒有必須進行依賴注入
        boolean autowireNecessary = false;
        /**
         * 經過getBean傳入進來的構造函數是否來指定須要推斷構造函數
         * 若傳遞進來的args不爲空,那麼就能夠直接選出對應的構造函數
         */
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                //判斷咱們的bean定義信息中的resolvedConstructorOrFactoryMethod(用來緩存咱們的已經解析的構造函數或者工廠方法)
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    //修改已經解析過的構造函數的標誌
                    resolved = true;
                    //修改標記爲ture 標識構造函數或者工廠方法已經解析過
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        //若被解析過
        if (resolved) {
            if (autowireNecessary) {
                //經過有參的構造函數進行反射調用
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //調用無參數的構造函數進行建立對象
                return instantiateBean(beanName, mbd);
            }
        }

        //經過bean的後置處理器進行選舉出合適的構造函數對象
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        //經過後置處理器解析出構造器對象不爲null或獲取bean定義中的注入模式是構造器注入或bean定義信息ConstructorArgumentValues或獲取經過getBean的方式傳入的構造器函數參數類型不爲null
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            //經過構造函數建立對象
            return autowireConstructor(beanName, mbd, ctors, args);
        }
        //使用無參數的構造函數調用建立對象
        return instantiateBean(beanName, mbd);
    }

  判斷是否暴露早期對象條件知足就暴露早期對象,把咱們的早期對象包裝成一個singletonFactory對象 該對象提供了一個getObject方法,該方法內部調用getEarlyBeanReference方法:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        //判讀咱們容器中是否有InstantiationAwareBeanPostProcessors類型的後置處理器
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //獲取咱們全部的後置處理器
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                //判斷咱們的後置處理器是否是實現了SmartInstantiationAwareBeanPostProcessor接口
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    //進行強制轉換
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    //挨個調用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }
        return exposedObject;
    }

  addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))方法:

/**
     * 該方法用於把早期對象包裝成一個ObjectFactory 暴露到三級緩存中 用於將解決循環依賴
     * @param beanName the name of the bean
     * @param singletonFactory the factory for the singleton object
     */
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        //加鎖
        synchronized (this.singletonObjects) {
            //單例緩存池中沒有包含當前的bean
            if (!this.singletonObjects.containsKey(beanName)) {
                //加入到三級緩存中 暴露早期對象用於解決循環依賴
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }

  ②屬性賦值:給咱們的屬性進行賦值(調用set方法進行賦值)populateBean(beanName, mbd, instanceWrapper)方法:

/**
     *給咱們的對象BeanWrapper屬性賦值
     * @param beanName bean的名稱
     * @param mbd bean的定義
     * @param bw bean實例包裝對象
     */
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        //若bw爲null的話,則說明對象沒有實例化
        if (bw == null) {
            //進入if說明對象有屬性,bw爲空,不能爲他設置屬性,那就在下面就執行拋出異常
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        /**
         * 在屬性被填充前,給 InstantiationAwareBeanPostProcessor 類型的後置處理器一個修改
         * bean 狀態的機會。官方的解釋是:讓用戶能夠自定義屬性注入。好比用戶實現一
         * 個 InstantiationAwareBeanPostProcessor 類型的後置處理器,並經過
         * postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息。
         *當時咱們發現系統中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationM沒有進行任何處理,
         *若咱們本身實現了這個接口 能夠自定義處理.....spring 留給咱們本身擴展接口的
         *特殊需求,直接使用配置中的信息注入便可。
         */
        boolean continueWithPropertyPopulation = true;
        //是否持有 InstantiationAwareBeanPostProcessor
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //獲取容器中的全部的BeanPostProcessor
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                //判斷咱們的後置處理器是否是InstantiationAwareBeanPostProcessor
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    //進行強制轉化
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //若存在後置處理器給咱們屬性賦值了,那麼返回false 能夠來修改咱們的開關變量,就不會走下面的邏輯了
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        // 返回值爲是否繼續填充 bean
                        // postProcessAfterInstantiation:若是應該在 bean上面設置屬性則返回 true,不然返回 false
                        // 通常狀況下,應該是返回true 。
                        // 返回 false 的話,將會阻止在此 Bean 實例上調用任何後續的 InstantiationAwareBeanPostProcessor 實
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }
        // 若是後續處理器發出中止填充命令,則終止後續操做
        if (!continueWithPropertyPopulation) {
            return;
        }

        //獲取bean定義的屬性
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        /**
         * 判斷咱們的bean的屬性注入模型
         * AUTOWIRE_BY_NAME 根據名稱注入
         * AUTOWIRE_BY_TYPE 根據類型注入
         */

        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            //把PropertyValues封裝成爲MutablePropertyValues
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            //根據bean的屬性名稱注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            //根據bean的類型進行注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            //把處理過的 屬性覆蓋原來的
            pvs = newPvs;
        }

        /**
         * 這裏又是一種後置處理,用於在 Spring 填充屬性到 bean 對象前,對屬性的值進行相應的處理,
         * 好比能夠修改某些屬性的值。這時注入到 bean 中的值就不是配置文件中的內容了,
         * 而是通過後置處理器修改後的內容
         */
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        //判斷是否須要檢查依賴
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        if (hasInstAwareBpps || needsDepCheck) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            //提出當前正在建立的beanWrapper 依賴的對象
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                //獲取全部的後置處理器
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //對依賴對象進行後置處理
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            //判斷是否檢查依賴
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        /**
         * 其實,上面只是完成了全部注入屬性的獲取,將獲取的屬性封裝在 PropertyValues 的實例對象 pvs 中,
         * 並無應用到已經實例化的 bean 中。而 #applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 方法,
         * 則是完成這一步驟的
         */
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

   ③初始化:進行對象初始化操做調用initializeBean,這裏會進行Aware接口進行方法的回調,而後調用Bean的後置處理器的Before方法(postProcessorsBeforeInitialization),而後Bean的初始化方法,最後調用Bean的後置處理器的After方法(PostProcessorsAfterInitialization)

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            //若咱們的Bean實現了Aware接口進行方法的回調
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //調用咱們的bean的後置處理器的postProcessorsBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //調用初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //調用咱們bean的後置處理器的PostProcessorsAfterInitialization方法 動態代理就是在這裏實現的
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

  進入調用初始化方法invokeInitMethods(beanName, wrappedBean, mbd)方法:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {

        //判斷咱們的容器中是否實現了InitializingBean接口
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //回調InitializingBean的afterPropertiesSet()方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            //咱們beanClass中看是否有本身定義的init方法
            String initMethodName = mbd.getInitMethodName();
            //判斷自定義的init方法名稱不叫afterPropertiesSet
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //調用咱們本身的初始化方法
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

  至此doCreateBean建立完成而後返回

  接下來bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd),爲何不直接等於sharedInstance,緣由可能剛剛建立的Bean是FactoryBean類型的Bean,若是是就要調用getObject方法來獲取真正的Bean,運用場景就是那些建立Bean的邏輯比較複雜的狀況下能夠用這個,好比Spring整合Mybatis的SqlSessionFactoryBean

  getObjectForBeanInstance(sharedInstance, name, beanName, mbd)方法:

protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

        // 若是name以&開頭,但beanInstance卻不是FactoryBean,則認爲有問題。
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            }
        }

          /**
             * 若是上面的判斷經過了,代表 beanInstance 多是一個普通的 bean,也多是一個
             * FactoryBean。若是是一個普通的 bean,這裏直接返回 beanInstance 便可。若是是
             * FactoryBean,則要調用工廠方法生成一個 bean 實例。
           */
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        Object object = null;
        if (mbd == null) {
            /**
             * 若是 mbd 爲空,則從緩存中加載 bean。FactoryBean 生成的單例 bean 會被緩存
             * 在 factoryBeanObjectCache 集合中,不用每次都建立
             */
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // 通過前面的判斷,到這裏能夠保證beanInstance是 FactoryBean類型的,因此能夠進行類型轉換
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // 若是 mbd 爲空,則判斷是否存在名字爲 beanName 的 BeanDefinition
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            //synthetic 字面意思是"合成的"。經過全局查找,我發如今 AOP 相關的類中會將該屬性設爲 true。
            //因此我以爲該字段可能表示某個 bean 是否是被 AOP 加強過,也就是 AOP 基於原始類合成了一個新的代理類。
            //不過目前只是猜想,沒有深究
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            //調用 getObjectFromFactoryBean 方法繼續獲取實例
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }

  接着調用object = getObjectFromFactoryBean(factory, beanName, !synthetic)方法:

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
           /**
             * FactoryBean 也有單例和非單例之分,針對不一樣類型的 FactoryBean,這裏有兩種處理方式:
             *   1. 單例 FactoryBean 生成的 bean 實例也認爲是單例類型。需放入緩存中,供後續重複使用
             *   2. 非單例 FactoryBean 生成的 bean 實例則不會被放入緩存中,每次都會建立新的實例
             **/
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                //從緩存中取bean實例,避免屢次建立bean實例
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    //使用工廠對象中建立實例
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (shouldPostProcess) {
                            //判斷當地的bean是否正在建立
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            beforeSingletonCreation(beanName);
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                            finally {
                                afterSingletonCreation(beanName);
                            }
                        }
                        // 這裏的beanName對應於FactoryBean的實現類,FactoryBean的實現類也會被實例化,並被緩存在singletonObjects中
                        if (containsSingleton(beanName)) {
                            // 這裏的beanName對應於FactoryBean的實現類,FactoryBean的實現類也會被實例化,並被緩存在singletonObjects中
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }

  使用工廠對象中建立實例object = doGetObjectFromFactoryBean(factory, beanName)方法:

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {

        Object object;
        try {
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //真正的調用工廠bean的getObject()方法
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }

        // Do not accept a null value for a FactoryBean that's not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            object = new NullBean();
        }
        return object;
    }

  處理多實例Bean

  mbd.isPrototype(),每次使用的時候再建立,由於不會加入到單實例緩衝池中,也就沒法解決循環依賴問題。

  至此doGetBean建立完成,返回,getBean建立完成

  最後獲取全部的bean的名稱(至此全部的單實例的bean已經加入到單實例Bean的緩存池中,所謂的單實例緩存池實際上就是一個ConcurrentHashMap),遍歷全部的bean名稱,根據beanName從單例緩存池中獲取全部的對象,而後判斷是不是SmartInitializingSingleton類型,是再觸發實例化以後的方法afterSingletonsInstantiated;

  完整的Spring IoC源碼解析見:Spring系列(三):Spring IoC源碼解析

3、getBean流程圖

  ① getBean流程圖:

  ② @AutoWired注入屬性和set方法注入流程圖:

 

  總結:經過對Spring IoC的getBean流程分析,瞭解了Bean的建立過程,先到單實例緩存池(ConcurrentHashMap)中獲取,取不到就調用createBean建立,建立成功後加入到單實例緩存池(ConcurrentHashMap)中,下次獲取的時候直接從JVM級別的緩存中獲取,Bean的生命週期,以及如何用三級緩存解決循環依賴,還有就是多實例爲何不能解決循環依賴問題。

相關文章
相關標籤/搜索