spring源碼分析七(獲取單例bean)

上一節(jié),我們從宏觀的角度分析了下bean實例化的預處理步驟,這一節(jié),我們重點來研究獲取單例bean,之前分析過的代碼就不在做分析了
我們直接從dogetBean說起一起再看下下面的這段代碼

Object sharedInstance = getSingleton(beanName);
        //當sharedInstance不為null.并且args參數(shù)為null的時候,說明就是想獲取bean,不是創(chuàng)建bean,這個時候,就會調(diào)用getObjectForBeanInstance
        if (sharedInstance != null && args == null) {
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

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

        // 如果name不為空,并且name是以&開頭,說明就是工廠bean
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            //如果此時的工廠bean是個null,直接返回
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            //再次判斷beanInstance是否是工廠bean,如果不是,直接拋出異常
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
            }
        }


        //走到這里,可以判斷此時的bean有可能是一個普通的bean,有可能是一個工廠bean,如果是普通bean,直接返回
        //如果是工廠bean,則調(diào)用生成一個bean實例
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        Object object = null;
        //如果mdb(RootBeanDefinition)為null,直接從緩存中獲取bean實例,spring會將生成好的單例bean緩存到currentHashMap中緩存起來
        //這樣,不用每次都去創(chuàng)建了
        if (mbd == null) {
            object = getCachedObjectForFactoryBean(beanName);
        }
        //走到這里,說明緩存沒有命中,也就是說當前的bean是一個FactoryBean
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            //查看此時的根據(jù)bean名稱查看beanDefinitionMap中是否存在當前bean,beanDefinitionMap前面已經(jīng)說過了,
            //當spring加載完后,會將加載的bean全部放到beanDefinitionMap
            if (mbd == null && containsBeanDefinition(beanName)) {
                //合并BeanDefinition
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            //判斷當前bean是否是合成的,synthetic合成的意思,但是這個地方?jīng)]有具體理解這個用法到底是啥意思,后期在研究哈
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            //從factoryBean中獲取bean
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }



#FactoryBeanRegistrySupport
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
           //檢查當前bean是否是單例
        if (factory.isSingleton() && containsSingleton(beanName)) {
            //緩存danlibean的map加鎖
            synchronized (getSingletonMutex()) {
                //從緩存中獲取bean
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    //證明緩存在不存在,調(diào)用doGetObjectFromFactoryBean方法獲取bean
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    //這里再一次從緩存中獲取一次bean,如果獲取到了,將alreadyThere賦值給Object,源碼解釋說是解決循環(huán)引用的時候的操作
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        //是否后置處理,
                        if (shouldPostProcess) {
                            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);
                            }
                        }
                        if (containsSingleton(beanName)) {
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            //走到這里,證明不是單例的,調(diào)用doGetObjectFromFactoryBean方法
            Object object = doGetObjectFromFactoryBean(factory, beanName);
             //判斷是否需要進行后置處理
            if (shouldPostProcess) {
                try {
                    //從factoryBean發(fā)布處理對象
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }



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

        Object object;
        try {
            //一些系統(tǒng)安全性檢查.咱們就不看了
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //調(diào)用getObject方法返回bean對象
                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);
        }


        if (object == null) {
            //是否是當前正在創(chuàng)建的bean,如果是,直接拋出異常
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            //將object定義為null返回
            object = new NullBean();
        }
        return object;
    }

簡單總結(jié)一下,代碼比較多,但是邏輯不復雜,
1:判斷是否是單例bean
2:從緩存在獲取bean,
3:對bean執(zhí)行后置處理
4:最后調(diào)用factory的getObject方法返回bean

好了,獲取bean就簡單分析到這里,代碼比較簡單,邏輯也不復雜,下一期,咱們再研究下創(chuàng)建單例bean的過程.Thanks!

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容