Spring之beanFactory

Spring本身就是一個容器(工廠)福侈,里面放的是Spring初始化的bean填具,我們只需從中取相應(yīng)的bean就可以了憨愉,BeanFactory就是訪問Spring bean容器的根接口(root interface),該接口定義了如下幾個方法:

Object getBean(String name) throws BeansException;
getBean方法:返回指定bean的實例臂港,該實例可以是共享的或獨立的森枪。Spring BeanFactory可以被用作Singleton或Prototype設(shè)計模式的替代视搏。 在Singleton bean的情況下,調(diào)用者可以保留對返回對象的引用县袱。將別名轉(zhuǎn)換回相應(yīng)的規(guī)范bean名稱浑娜。如果在此工廠實例中找不到bean 將詢問父工廠。

boolean containsBean(String name);
containsBean方法:如果給定的名稱是別名式散,則它將被轉(zhuǎn)換回相應(yīng)的規(guī)范bean名稱筋遭。如果找到與給定名稱匹配bean的定義或單例實例,則此方法將返回true

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
isSingleton方法:判斷該bean是否是共享的單例暴拄,注意:此方法返回false并不能清楚地指示獨立實例漓滔。 它表示非單例實例,也可以對應(yīng)于作用域bean揍移。 使用isPrototype操作顯式檢查獨立實例次和。

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
isPrototype:判斷該bean是否是原型反肋,注意:此方法返回false并不能清楚地指示單個對象那伐。 它表示非獨立實例,也可以對應(yīng)于范圍bean石蔗。 使用isSingleton操作顯式檢查共享單例實例罕邀。

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
isTypeMatch方法:檢查給定名稱的bean是否與指定的類型匹配。 即檢查給定名稱的getBean調(diào)用是否將返回可分配給指定目標類型的對象养距。

Class<?> getType(String name) throws NoSuchBeanDefinitionException;
getType方法:確定給定名稱的bean的類型诉探。 即確定getBean為給定名稱返回的對象類型。對于FactoryBean返回FactoryBean創(chuàng)建的對象類型棍厌。由FactoryBean.getObjectType方法實現(xiàn)

String[] getAliases(String name);
getAliases方法:返回給定bean名稱的別名(如果有)肾胯。 當在getBean調(diào)用中使用時所有這些別名都指向同一個bean。

ListableBeanFactory也是一個接口耘纱,該接口繼承了beanFactory接口敬肚,該接口定義了如下幾個方法:

boolean containsBeanDefinition(String beanName);
containsBeanDefinition方法:判斷傳入的beanName是否在bean factroy中被定義。

int getBeanDefinitionCount();
getBeanDefinitionCount方法:返回bean factory中的定義定義了的bean的個數(shù)束析。

String[] getBeanDefinitionNames();
getBeanDefinitionNames方法:返回bean factory中定義了的bean的名字艳馒。

String[] getBeanNamesForType(ResolvableType type);
getBeanNamesForType方法:返回與傳入的類型(type)(包括子類)匹配的bean的名稱,從bean定義或FactoryBeans的getObjectType值判斷员寇。

String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
getBeanNamesForAnnotation方法:返回bean中提供Annotation類型的的所有名稱弄慰,不創(chuàng)建任何bean實例。

Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
getBeansWithAnnotation:同上蝶锋,只是返回類型不同

<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
            throws NoSuchBeanDefinitionException;
findAnnotationOnBean方法:在指定的bean上查找annotationType的注釋(Annotation)陆爽,如果在給定的類本身上找不到注釋,則遍歷實現(xiàn)的接口和繼承的父類扳缕。

ConfigurableListableBeanFactory繼承了ListableBeanFactory,和AutowireCapableBeanFactory, ConfigurableBeanFactory 三個接口慌闭,接口ConfigurableListableBeanFactory定義了如下的方法:

void ignoreDependencyType(Class<?> type);
ignoreDependencyType方法:忽略自動裝配的依賴類型恶守,舉個例子,String類型忽略后就是none贡必。

void ignoreDependencyInterface(Class<?> ifc);
ignoreDependencyInterface方法:忽略自動裝配依賴關(guān)系的接口兔港。

void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
registerResolvableDependency方法:注冊一個特殊的依賴關(guān)系的自動注入。

boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
            throws NoSuchBeanDefinitionException;
isAutowireCandidate方法:判斷指定的bean是否可以作為autowire候選者仔拟,并將其注入到與之匹配的依賴關(guān)系的bean中衫樊。

BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
getBeanDefinition方法:返回指定bean的已注冊BeanDefinition,允許訪問其屬性值和構(gòu)造函數(shù)參數(shù)值(可以在bean工廠后處理期間修改)利花。返回的BeanDefinition對象不應(yīng)是副本科侈,而應(yīng)是在工廠中注冊的原始定義對象。 這意味著如果需要炒事,它應(yīng)該可以轉(zhuǎn)換為更具體的實現(xiàn)類型臀栈。

Iterator<String> getBeanNamesIterator();
getBeanNamesIterator方法:返回工廠管理的所有bean名稱的統(tǒng)一視圖。

void clearMetadataCache();
clearMetadataCache方法:清除合并的bean定義緩存挠乳,刪除尚未被認為有資格進行完整元數(shù)據(jù)緩存的bean條目权薯,通常在更改原始bean定義后觸發(fā),例如 在應(yīng)用BeanFactoryPostProcessor之后睡扬,請注意盟蚣,此時已創(chuàng)建的bean的元數(shù)據(jù)將保留。

void freezeConfiguration();
freezeConfiguration方法:凍結(jié)所有bean定義卖怜,表明注冊的bean定義不會被修改或進一步后處理屎开。

boolean isConfigurationFrozen();
isConfigurationFrozen方法:返回該工廠的bean定義是否被凍結(jié),即不應(yīng)該進一步修改或后處理马靠。

void preInstantiateSingletons() throws BeansException;
preInstantiateSingletons方法:確保所有non-lazy-init單例都被實例化奄抽,同時考慮FactoryBeans, 如果需要甩鳄,通常在出廠設(shè)置結(jié)束時調(diào)用逞度。

DefaultListableBeanFactory類實現(xiàn)了ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable等接口,繼承了AbstractAutowireCapableBeanFactory類娩贷。DefaultListableBeanFactory實現(xiàn)了如下幾個方法:

// Implementation of remaining BeanFactory methods

1.T getBean(Class<T> requiredType) throws BeansException 

2.T getBean(Class<T> requiredType, Object... args) throws BeansException 

3.public <T> T getBean(Class<T> requiredType, Object... args)throws BeansException {
        NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
        if (namedBean != null) {
                       //返回相應(yīng)的bean實例(可以為null)第晰。
            return namedBean.getBeanInstance();
        }
                //返回父類的bean工廠,如果沒有則返回null
        BeanFactory parent = getParentBeanFactory();
        if (parent != null) {
                        //返回指定bean的實例彬祖,該實例可以是共享的或獨立的茁瘦。
            return parent.getBean(requiredType, args);
        }
        throw new NoSuchBeanDefinitionException(requiredType);
    }

// Implementation of ListableBeanFactory interface
1.boolean containsBeanDefinition(String beanName)

2.int getBeanDefinitionCount()

3.String[] getBeanDefinitionNames()

4.String[] getBeanNamesForType(ResolvableType type)

//
5.public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
        if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
            return doGetBeanNamesForType(ResolvableType.forRawClass(type),                                                  includeNonSingletons, allowEagerInit);
        }
        Map<Class<?>, String[]> cache =
                (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
        String[] resolvedBeanNames = cache.get(type);
        if (resolvedBeanNames != null) {
            return resolvedBeanNames;
        }
        resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
        if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
            cache.put(type, resolvedBeanNames);
        }
        return resolvedBeanNames;
    }


6.private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        List<String> result = new ArrayList<String>();

        //檢查所有bean的定義
        for (String beanName : this.beanDefinitionNames) {
            // Only consider bean as eligible if the bean name
            // is not defined as alias for some other bean.
                        //如果bean名稱未定義為其他bean的別名,那么他就是合格的
            if (!isAlias(beanName)) {
                try {
                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    // Only check bean definition if it is complete.
                    if (!mbd.isAbstract() && (allowEagerInit ||
                            ((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
                                    !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                        // In case of FactoryBean, match object created by FactoryBean.
                        boolean isFactoryBean = isFactoryBean(beanName, mbd);
                        BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                        boolean matchFound =
                                (allowEagerInit || !isFactoryBean ||
                                        (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
                                (includeNonSingletons ||
                                        (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
                                isTypeMatch(beanName, type);
                        if (!matchFound && isFactoryBean) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            beanName = FACTORY_BEAN_PREFIX + beanName;
                            matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
                        }
                        if (matchFound) {
                            result.add(beanName);
                        }
                    }
                }
                catch (CannotLoadBeanClassException ex) {
                    if (allowEagerInit) {
                        throw ex;
                    }
                    // Probably contains a placeholder: let's ignore it for type matching purposes.
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
                    }
                    onSuppressedException(ex);
                }
                catch (BeanDefinitionStoreException ex) {
                    if (allowEagerInit) {
                        throw ex;
                    }
                    // Probably contains a placeholder: let's ignore it for type matching purposes.
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
                    }
                    onSuppressedException(ex);
                }
            }
        }

        // Check manually registered singletons too.
        for (String beanName : this.manualSingletonNames) {
            try {
                // In case of FactoryBean, match object created by FactoryBean.
                if (isFactoryBean(beanName)) {
                    if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
                        result.add(beanName);
                        // Match found for this bean: do not match FactoryBean itself anymore.
                        continue;
                    }
                    // In case of FactoryBean, try to match FactoryBean itself next.
                    beanName = FACTORY_BEAN_PREFIX + beanName;
                }
                // Match raw bean instance (might be raw FactoryBean).
                if (isTypeMatch(beanName, type)) {
                    result.add(beanName);
                }
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Shouldn't happen - probably a result of circular reference resolution...
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to check manually registered singleton with name '" + beanName + "'", ex);
                }
            }
        }

        return StringUtils.toStringArray(result);
    }



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市储笑,隨后出現(xiàn)的幾起案子甜熔,更是在濱河造成了極大的恐慌,老刑警劉巖突倍,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腔稀,死亡現(xiàn)場離奇詭異盆昙,居然都是意外死亡,警方通過查閱死者的電腦和手機焊虏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門淡喜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诵闭,你說我怎么就攤上這事炼团。” “怎么了疏尿?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵瘟芝,是天一觀的道長。 經(jīng)常有香客問我褥琐,道長锌俱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任敌呈,我火速辦了婚禮贸宏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驱富。我一直安慰自己锚赤,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布褐鸥。 她就那樣靜靜地躺著,像睡著了一般赐稽。 火紅的嫁衣襯著肌膚如雪叫榕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天姊舵,我揣著相機與錄音晰绎,去河邊找鬼。 笑死括丁,一個胖子當著我的面吹牛荞下,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播史飞,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尖昏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了构资?” 一聲冷哼從身側(cè)響起抽诉,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吐绵,沒想到半個月后迹淌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體河绽,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年唉窃,在試婚紗的時候發(fā)現(xiàn)自己被綠了耙饰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡纹份,死狀恐怖榔幸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矮嫉,我是刑警寧澤削咆,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蠢笋,受9級特大地震影響拨齐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜昨寞,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一瞻惋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧援岩,春花似錦歼狼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至添瓷,卻和暖如春梅屉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鳞贷。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工坯汤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搀愧。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓惰聂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咱筛。 傳聞我的和親對象是個殘疾皇子搓幌,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容