BeanFactory 體系結(jié)構(gòu)

前一篇 Spring Ioc 概述 中已對(duì) Spring Ioc 做了一些基本的介紹,在文章的最后分別舉了使用 ClassPathXmlApplicationContext 和 AnnotationConfigApplicationContext 來(lái)創(chuàng)建 Spring Ioc 容器的例子喉刘。分析這兩個(gè)類的繼承關(guān)系腹殿,他們均為 ApplicationContext 的實(shí)現(xiàn)類科阎,因此就先通過(guò) ClassPathXmlApplicationContext 的繼承關(guān)系來(lái)分析碗淌。

  • ClassPathXmlApplicationContext 類圖


    images

    從類圖中分析 ClassPathXmlApplicationContext 的類繼承關(guān)系

    ClassPathXmlApplicationContext
        -- AbstractXmlApplicationContext
            -- AbstractRefreshableConfigApplicationContext
                -- InitializingBean
                -- BeanNameAware
                -- AbstractRefreshableApplicationContext
                    -- AbstractApplicationContext
                        -- DefaultResourceLoader
                        -- ConfigurableApplicationContext
                            -- ApplicationContext
    ApplicationContext
        -- EnvironmentCapable
        -- MessageSource
        -- ApplicationEventPublisher
        -- ResourcePatternResolver
        -- ListableBeanFactory
        -- HierarchicalBeanFactory
            -- BeanFactory                      
    

從類的繼承關(guān)系可以看出掩完,ClassPathXmlApplicationContext 實(shí)現(xiàn)了 ApplicationContext 接口馆截,而 ApplicationContext 接口又是在 BeanFactory 接口的基礎(chǔ)上進(jìn)行了擴(kuò)展充活。因此先從 BeanFactory 及其子接口開(kāi)始分析蜂莉。

BeanFactory
  • BeanFactory 體系結(jié)構(gòu)


    images

    BeanFactory 的體系結(jié)構(gòu)圖中,包含了一系列的接口及實(shí)現(xiàn)類

    1. 接口

      -- BeanFactory(一級(jí)接口)
          一級(jí)接口混卵,定義了獲取 Bean映穗、BeanType、單例多例的方法
          
          -- ListableBeanFactory(二級(jí)接口)
          可列表化的BeanFactory幕随,添加了根據(jù)BeanDefinition相關(guān)的一些操作蚁滋,以及列表化返回結(jié)果的接口
          
          -- HierarchicalBeanFactory(二級(jí)接口)
              實(shí)現(xiàn)了工廠的分層,引入父子容器的概念
              1. 父子容器是相互隔離的赘淮,他們內(nèi)部可以存在名稱相同的 Bean
              2. 子容器可以訪問(wèn)父容器的Bean辕录,父容器不能訪問(wèn)子容器的Bean
              3. 調(diào)用子容器的getBean方法,會(huì)沿著當(dāng)前的容器向上層查找梢卸,直到找到對(duì)應(yīng)的Bean為止
              4. 子容器可以通過(guò)任何方式注入父容器中的Bean走诞,而父容器無(wú)法注入子容器的Bean
              
              -- ConfigurableBeanFactory(三級(jí)接口)
              對(duì) HierarchicalBeanFactory 增強(qiáng),同時(shí)繼承了 SingletonBeanRegistry
          
          -- AutowireCapableBeanFactory(二級(jí)接口)
              1. 對(duì)于想要擁有自動(dòng)裝配能力蛤高,并且想要把這種能力暴露給外部應(yīng)用BeanFactory類需要實(shí)現(xiàn)此接口速梗。
              2. 正常情況下不要使用此接口,應(yīng)該更傾向于使用BeanFactory或者ListableBeanFactory接口襟齿。
              3. 此接口主要是針對(duì)框架之外姻锁,沒(méi)有向Spring托管的Bean的應(yīng)用。通過(guò)暴露此功能猜欺,Spring框架之外的程序位隶,具有自動(dòng)裝配Spring的功能
              4. 需要注意的是ApplicationContext并沒(méi)有實(shí)現(xiàn)此接口。因?yàn)閼?yīng)用代碼很少使用此功能开皿。如果確實(shí)需要的話可以調(diào)用ApplicationContext.getAutowireCapableBeanFactory()的方法涧黄,來(lái)獲取此接口的實(shí)例
              5. 如果一個(gè)類實(shí)現(xiàn)了此接口,那么很大程度上它還需要實(shí)現(xiàn)BeanFactoryWare接口赋荆。它可以在應(yīng)用上下文中返回BeanFactory;
                  
                  -- ConfigurableListableBeanFactory(四級(jí)接口)
      
      public interface BeanFactory {
      
          /**作用:如果在使用beanName獲取Bean時(shí)笋妥,在BeanName前添加這個(gè)前綴, 
          *  那么使用這個(gè)BeanName獲得的Bean實(shí)例是其所在FactoryBean的實(shí)例窄潭,
          *  也就是實(shí)現(xiàn) FactoryBean 接口的那個(gè)類的Bean實(shí)例 
          **/
          String FACTORY_BEAN_PREFIX = "&";
      
          // 定義四個(gè)獲取 Bean 的方法
          Object getBean(String name) throws BeansException;
          <T> T getBean(String name, Class<T> requiredType) throws BeansException;
          Object getBean(String name, Object... args) throws BeansException;
          <T> T getBean(Class<T> requiredType) throws BeansException;
          <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
      
          // 
          <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
          <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
      
          // 是否包含對(duì)應(yīng)名稱的Bean
          boolean containsBean(String name);
      
          // 單例還是多例
          boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
          boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
      
          // Bean 名稱與類型是否匹配
          boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
          boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
      
          // 獲取 BeanName 對(duì)應(yīng)的 class
          @Nullable
          Class<?> getType(String name) throws NoSuchBeanDefinitionException;
          @Nullable
          Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
          
          // 根據(jù)實(shí)例的名字獲取實(shí)例的別名
          String[] getAliases(String name);
      
      }
      
    2. 抽象類

      • AbstractBeanFactory
        實(shí)現(xiàn)了 ConfigurableBeanFactory 接口的大部分功能

        public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
        }
        
      • AbstractAutowireCapableBeanFactory
        繼承自 AbstractBeanFactory 春宣,并額外實(shí)現(xiàn)了二級(jí)接口 AutowireCapableBeanFactory

        public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {
        }
        
    3. 實(shí)現(xiàn)類

      • DefaultListableBeanFactory
        繼承自 AbstractAutowireCapableBeanFactory ,實(shí)現(xiàn)了最強(qiáng)大的四級(jí)接口 ConfigurableListableBeanFactory 嫉你,并實(shí)現(xiàn)了一個(gè)外來(lái)接口 BeanDefinitionRegistry 月帝,它并非抽象類。

        public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
        }
        
      • XmlBeanFactory
        繼承自 DefaultListableBeanFactory 幽污,重寫(xiě)了一些功能嚷辅,使自己更強(qiáng)大。

        public class XmlBeanFactory extends DefaultListableBeanFactory {
        }
        
    4. 額外的接口BeanDefinitionRegistry
      這個(gè)接口基本用來(lái)操作定義在工廠內(nèi)部的BeanDefinition的

      public interface BeanDefinitionRegistry extends AliasRegistry { 
          // 給定bean名稱距误,注冊(cè)一個(gè)新的bean定義 
          void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException; 
          
          /*
          * 根據(jù)指定Bean名移除對(duì)應(yīng)的Bean定義 
          */ 
          void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; 
          
          /*
          * 根據(jù)指定bean名得到對(duì)應(yīng)的Bean定義
          */ 
          BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; 
          
          /** 查找簸搞,指定的Bean名是否包含Bean定義 */ 
          boolean containsBeanDefinition(String beanName); 
          
          String[] getBeanDefinitionNames();//返回本容器內(nèi)所有注冊(cè)的Bean定義名稱 
          int getBeanDefinitionCount();//返回本容器內(nèi)注冊(cè)的Bean定義數(shù)目 
          boolean isBeanNameInUse(String beanName);//指定Bean名是否被注冊(cè)過(guò)扁位。
      }
      
  • BeanDefinition 體系結(jié)構(gòu)


    images
    1. AttributeAccessor
    // 定義用于附加和訪問(wèn)元數(shù)據(jù)的通用的接口,來(lái)自任意對(duì)象
    public interface AttributeAccessor {
        // 將name的屬性值設(shè)置為value
        void setAttribute(String name, Object value);
      // 獲取name的屬性值趁俊,如果該屬性不存在贤牛,則返回Null
        Object getAttribute(String name);
      // 刪除name的屬性值,如果找不到Name屬性的值則返回Null
        Object removeAttribute(String name);
        // 如果name屬性值存在則返回true则酝,否者返回false
        boolean hasAttribute(String name);
        // 返回所有的屬性名稱
        String[] attributeNames();
    
    }
    
    1. BeanMetadataElement
    public interface BeanMetadataElement {
        /**
        * Return the configuration source {@code Object} for this metadata element
        * (may be {@code null}).
        */
        @Nullable
        Object getSource();
    
    }
    

至此 BeanFactory 的體系結(jié)構(gòu)便簡(jiǎn)單介紹完了殉簸。BeanFactory 體系中核心主要是:

  1. BeanFactory:Bean 工廠定義了一系列操作 Bean 的方法
  2. BeanDefinition: Spring 對(duì) Bean 信息的一個(gè)抽象,其中包含了 Bean 的作用域沽讹、懶加載信息般卑、class、 beanName 等一列 Bean 的元數(shù)據(jù)信息
  3. BeanDefinitionRegistry: BeanDefinition 的注冊(cè)器爽雄,將 Bean 配置信息轉(zhuǎn)化為 BeanDefinition 對(duì)象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蝠检,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子挚瘟,更是在濱河造成了極大的恐慌叹谁,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乘盖,死亡現(xiàn)場(chǎng)離奇詭異焰檩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)订框,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)析苫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人穿扳,你說(shuō)我怎么就攤上這事衩侥。” “怎么了矛物?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵茫死,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我履羞,道長(zhǎng)峦萎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任吧雹,我火速辦了婚禮骨杂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雄卷。我一直安慰自己,他們只是感情好蛤售,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布丁鹉。 她就那樣靜靜地躺著妒潭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揣钦。 梳的紋絲不亂的頭發(fā)上雳灾,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音冯凹,去河邊找鬼谎亩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宇姚,可吹牛的內(nèi)容都是我干的匈庭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浑劳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼阱持!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起魔熏,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衷咽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蒜绽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體镶骗,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年躲雅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卖词。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吏夯,死狀恐怖此蜈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情噪生,我是刑警寧澤裆赵,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站跺嗽,受9級(jí)特大地震影響战授,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桨嫁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一植兰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧璃吧,春花似錦楣导、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)噩凹。三九已至,卻和暖如春毡咏,著一層夾襖步出監(jiān)牢的瞬間驮宴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工呕缭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堵泽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓恢总,卻偏偏與公主長(zhǎng)得像迎罗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子离熏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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