BeanFactory伤溉、ApplicationContext以及FactoryBean

1.BeanFactory與ApplicationContext區(qū)別

容器是spring的核心,管理IOC所有的組件妻率。spring的兩種容器:

  • BeanFactoy
  • ApplicationContext

1.1 BeanFactory的功能

BeanFactory乱顾,以Factory結(jié)尾,表示它是一個工廠類(接口)宫静, 它負責生產(chǎn)和管理bean的一個工廠走净。在Spring中,BeanFactory是IOC容器的核心接口孤里,它的職責包括:實例化伏伯、定位、配置應(yīng)用程序中的對象及建立這些對象間的依賴扭粱。BeanFactory只是個接口,并不是IOC容器的具體實現(xiàn)震檩,但是Spring容器給出了很多種實現(xiàn)琢蛤,如 DefaultListableBeanFactory、XmlBeanFactory抛虏、ApplicationContext等博其。

注意,BeanFactory 只能管理單例(Singleton)Bean 的生命周期迂猴。它不能管理原型(prototype,非單例)Bean 的生命周期慕淡。這是因為原型 Bean 實例被創(chuàng)建之后便被傳給了客戶端,容器失去了對它們的引用。

1.2 ApplicationContext的功能

包含兩個子接口:

  • ConfigurableApplicationContext
  • WebApplicationContext

如果說BeanFactory是Spring的心臟沸毁,那么ApplicationContext就是完整的軀體了峰髓,ApplicationContext由BeanFactory派生而來,提供了更多面向?qū)嶋H應(yīng)用的功能息尺。在BeanFactory中携兵,很多功能需要以編程的方式實現(xiàn),而在ApplicationContext中則可以通過配置實現(xiàn)搂誉。

BeanFactorty接口提供了配置框架及基本功能徐紧,但是無法支持spring的aop功能和web應(yīng)用。而ApplicationContext接口作為BeanFactory的派生炭懊,因而提供BeanFactory所有的功能并级。而且ApplicationContext還在功能上做了擴展,相較于BeanFactorty侮腹,ApplicationContext還提供了以下的功能:
(1)MessageSource, 提供國際化的消息訪問
(2)資源訪問嘲碧,如URL和文件
(3)事件傳播特性,即支持aop特性
(4)載入多個(有繼承關(guān)系)上下文 父阻,使得每一個上下文都專注于一個特定的層次呀潭,比如應(yīng)用的web層
ApplicationContext:是IOC容器另一個重要接口钉迷, 它繼承了BeanFactory的基本功能, 同時也繼承了容器的高級功能钠署,如:MessageSource(國際化資源接口)糠聪、ResourceLoader(資源加載接口)、ApplicationEventPublisher(應(yīng)用事件發(fā)布接口)等谐鼎。

ApplicationContext常用的三個實現(xiàn)類:

  • a舰蟆、ClassPathXmlApplication:把上下文文件當成類路徑資源
  • b、FileSystemXmlApplication:從文件系統(tǒng)中的XML文件載入上下文定義信息
  • c狸棍、XmlWebApplicationContext:從Web系統(tǒng)中的XML文件載入上下文定義信息

1.3 二者的區(qū)別

1.BeanFactroy采用的是延遲加載形式來注入Bean的身害,即只有在使用到某個Bean時(調(diào)用getBean()),才對該Bean進行加載實例化草戈,這樣塌鸯,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問題。而ApplicationContext則相反唐片,它是在容器啟動時丙猬,一次性創(chuàng)建了所有的Bean。這樣费韭,在容器啟動時茧球,我們就可以發(fā)現(xiàn)Spring中存在的配置錯誤。 相對于基本的BeanFactory星持,ApplicationContext 唯一的不足是占用內(nèi)存空間抢埋。當應(yīng)用程序配置Bean較多時,程序啟動較慢督暂。

BeanFacotry延遲加載,如果Bean的某一個屬性沒有注入揪垄,BeanFacotry加載后,直至第一次使用調(diào)用getBean方法才會拋出異常逻翁;而ApplicationContext則在初始化自身是檢驗福侈,這樣有利于檢查所依賴屬性是否注入;所以通常情況下我們選擇使用 ApplicationContext卢未。
應(yīng)用上下文則會在上下文啟動后預(yù)載入所有的單實例Bean肪凛。通過預(yù)載入單實例bean ,確保當你需要的時候,你就不用等待辽社,因為它們已經(jīng)創(chuàng)建好了伟墙。

2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用滴铅,但兩者之間的區(qū)別是:BeanFactory需要手動注冊戳葵,而ApplicationContext則是自動注冊。(Applicationcontext比 beanFactory 加入了一些更好使用的功能汉匙。而且 beanFactory 的許多功能需要通過編程實現(xiàn)而 Applicationcontext 可以通過配置實現(xiàn)拱烁。比如后處理 bean 生蚁, Applicationcontext 直接配置在配置文件即可而 beanFactory 這要在代碼中顯示的寫出來才可以被容器識別。 )

3.beanFactory主要是面對與 spring 框架的基礎(chǔ)設(shè)施戏自,面對 spring 自己邦投。而 Applicationcontex 主要面對與 spring 使用的開發(fā)者∩帽剩基本都會使用 Applicationcontex 并非 beanFactory 志衣。

2.AnnotationConfigApplicationContext類層次

    public void test01(){
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Ch9MainConfig.class);
        System.out.println(app);
        TestService testService = app.getBean(TestService.class);

3.FactoryBean

3.1 BeanFactory與FactoryBean的區(qū)別

BeanFactory是個Factory,也就是IOC容器或?qū)ο蠊S猛们,F(xiàn)actoryBean是個Bean念脯。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)來進行管理的弯淘。但對FactoryBean而言绿店,這個Bean不是簡單的Bean,而是一個能生產(chǎn)或者修飾對象生成的工廠Bean,它的實現(xiàn)與設(shè)計模式中的工廠模式和修飾器模式類似庐橙。

BeanFactory定義了IOC容器的最基本形式假勿,并提供了IOC容器應(yīng)遵守的的最基本的接口,也就是Spring IOC所遵守的最底層和最基本的編程規(guī)范怕午。在Spring代碼中废登,BeanFactory只是個接口淹魄,并不是IOC容器的具體實現(xiàn)郁惜,但是Spring容器給出了很多種實現(xiàn),如 DefaultListableBeanFactory甲锡、XmlBeanFactory兆蕉、ApplicationContext等,都是附加了某種功能的實現(xiàn)缤沦。

一般情況下虎韵,Spring通過反射機制利用<bean>的class屬性指定實現(xiàn)類實例化Bean,在某些情況下缸废,實例化Bean過程比較復雜包蓝,如果按照傳統(tǒng)的方式锥腻,則需要在<bean>中提供大量的配置信息别威。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案沪铭。Spring為此提供了一個org.springframework.bean.factory.FactoryBean的工廠類接口届巩,用戶可以通過實現(xiàn)該接口定制實例化Bean的邏輯硅瞧。
FactoryBean接口對于Spring框架來說占用重要的地位,Spring自身就提供了70多個FactoryBean的實現(xiàn)恕汇。它們隱藏了實例化一些復雜Bean的細節(jié)腕唧,給上層應(yīng)用帶來了便利或辖。


3.2 FactoryBean的詳細信息

一個Bean想要實現(xiàn) FactoryBean ,必須實現(xiàn)以下三個接口:

    1. Object getObject():返回由FactoryBean創(chuàng)建的Bean的實例
    1. boolean isSingleton():確定由FactoryBean創(chuàng)建的Bean的作用域是singleton還是prototype枣接;
    1. getObjectType():返回FactoryBean創(chuàng)建的Bean的類型颂暇。

JamesFactoryBean類實現(xiàn)FactoryBean<Monkey>接口

public class JamesFactoryBean implements FactoryBean<Monkey> {

    @Override
    public Monkey getObject() throws Exception {
        // TODO Auto-generated method stub
        return new Monkey();
    }

    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return Monkey.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

FactoryBean測試類

public class Ch6Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Ch6MainConfig.class);

        System.out.println("IOC容器創(chuàng)建完成........");

        Object bean1 = app.getBean("jamesFactoryBean");
        Object bean2 = app.getBean("jamesFactoryBean");//取Money
        System.out.println("bean1的類型=" + bean1.getClass());
        System.out.println(bean1 == bean2);

        Object bean3 = app.getBean("&jamesFactoryBean");
        System.out.println("bean3的類型=" + bean3.getClass());

結(jié)果:

bean1的類型=class com.wangzhen.ch6.bean.Monkey
true
bean3的類型=class com.wangzhen.ch6.config.JamesFactoryBean

注意:如果想通過spring拿到j(luò)amesFactoryBean,需要在名稱前加 & 符號

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末月腋,一起剝皮案震驚了整個濱河市蟀架,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌榆骚,老刑警劉巖片拍,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妓肢,居然都是意外死亡捌省,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門碉钠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纲缓,“玉大人,你說我怎么就攤上這事喊废∽8撸” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵污筷,是天一觀的道長工闺。 經(jīng)常有香客問我,道長瓣蛀,這世上最難降的妖魔是什么陆蟆? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮惋增,結(jié)果婚禮上叠殷,老公的妹妹穿的比我還像新娘。我一直安慰自己诈皿,他們只是感情好林束,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著稽亏,像睡著了一般壶冒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上措左,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天依痊,我揣著相機與錄音,去河邊找鬼。 笑死胸嘁,一個胖子當著我的面吹牛瓶摆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播性宏,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼群井,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了毫胜?” 一聲冷哼從身側(cè)響起书斜,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酵使,沒想到半個月后荐吉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡口渔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年样屠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缺脉。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡痪欲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攻礼,到底是詐尸還是另有隱情业踢,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布礁扮,位于F島的核電站知举,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏深员。R本人自食惡果不足惜负蠕,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一蛙埂、第九天 我趴在偏房一處隱蔽的房頂上張望倦畅。 院中可真熱鬧,春花似錦绣的、人聲如沸叠赐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芭概。三九已至,卻和暖如春惩嘉,著一層夾襖步出監(jiān)牢的瞬間罢洲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惹苗,地道東北人殿较。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像桩蓉,于是被迫代替她去往敵國和親淋纲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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