<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring系列之BeanFactory與ApplicationContext

          共 7556字,需瀏覽 16分鐘

           ·

          2020-09-24 21:21


          一、BeanFactory


          BeanFactory 是 Spring 的“心臟”。它就是 Spring IoC 容器的真面目。Spring 使用 BeanFactory 來實例化、配置和管理 Bean。


          BeanFactory:是IOC容器的核心接口, 它定義了IOC的基本功能,我們看到它主要定義了getBean方法。getBean方法是IOC容器獲取bean對象和引發(fā)依賴注入的起點。方法的功能是返回特定的名稱的Bean。


          BeanFactory 是初始化 Bean 和調(diào)用它們生命周期方法的“吃苦耐勞者”。注意,BeanFactory 只能管理單例(Singleton)Bean 的生命周期。它不能管理原型(prototype,非單例)Bean 的生命周期。這是因為原型 Bean 實例被創(chuàng)建之后便被傳給了客戶端,容器失去了對它們的引用。


          BeanFactory有著龐大的繼承、實現(xiàn)體系,有眾多的子接口、實現(xiàn)類。來看一下BeanFactory的基本類體系結(jié)構(gòu)(接口為主):



          這是我畫的BeanFactory基本的類體系結(jié)構(gòu),這里沒有包括強大的ApplicationContext體系。


          具體:


            1、BeanFactory作為一個主接口不繼承任何接口,暫且稱為一級接口
            2、有3個子接口繼承了它,進行功能上的增強。這3個子接口稱為二級接口
            3、ConfigurableBeanFactory可以被稱為三級接口,對二級接口HierarchicalBeanFactory進行了再次增強,它還繼承了另一個外來的接口SingletonBeanRegistry

            4、ConfigurableListableBeanFactory是一個更強大的接口,繼承了上述的所有接口,無所不包,稱為四級接口
            (這4級接口是BeanFactory的基本接口體系。繼續(xù),下面是繼承關(guān)系的2個抽象類和2個實現(xiàn)類:)
            5、AbstractBeanFactory作為一個抽象類,實現(xiàn)了三級接口ConfigurableBeanFactory大部分功能。
            6、AbstractAutowireCapableBeanFactory同樣是抽象類,繼承自AbstractBeanFactory,并額外實現(xiàn)了二級接口AutowireCapableBeanFactory
            7、DefaultListableBeanFactory繼承自AbstractAutowireCapableBeanFactory,實現(xiàn)了最強大的四級接口ConfigurableListableBeanFactory,并實現(xiàn)了一個外來接口BeanDefinitionRegistry,它并非抽象類。
            8、最后是最強大的XmlBeanFactory,繼承自DefaultListableBeanFactory,重寫了一些功能,使自己更強大。


          總結(jié):


          BeanFactory的類體系結(jié)構(gòu)看似繁雜混亂,實際上由上而下井井有條,非常容易理解。

          再來看一下BeanFactory的源碼:


          package?org.springframework.beans.factory;

          public?interface?BeanFactory?{

          ????/**
          ?????* 用來引用一個實例,或把它和工廠產(chǎn)生的Bean區(qū)分開,就是說,如果一個FactoryBean的名字為a,那么,&a會得到那個Factory
          ?????*/

          ????String FACTORY_BEAN_PREFIX = "&";

          ????/*
          ?????* 四個不同形式的getBean方法,獲取實例
          ?????*/

          ????Object getBean(String name)?throws?BeansException;
          ???? T getBean(String name, Class requiredType)?throws?BeansException;
          ???? T getBean(Class requiredType)?throws?BeansException;
          ????Object getBean(String name, Object... args)?throws?BeansException;
          ????boolean?containsBean(String name); // 是否存在
          ????boolean?isSingleton(String name)?throws?NoSuchBeanDefinitionException;// 是否為單實例
          ????boolean?isPrototype(String name)?throws?NoSuchBeanDefinitionException;// 是否為原型(多實例)
          ????boolean?isTypeMatch(String name, Class targetType)
          ????????????throws?NoSuchBeanDefinitionException
          ;// 名稱、類型是否匹配
          ????Class getType(String name) throws?NoSuchBeanDefinitionException; // 獲取類型
          ????String[] getAliases(String name);// 根據(jù)實例的名字獲取實例的別名

          }


          具體:


            1、4個獲取實例的方法。getBean的重載方法。
            2、4個判斷的方法。判斷是否存在,是否為單例、原型,名稱類型是否匹配。
            3、1個獲取類型的方法、一個獲取別名的方法。根據(jù)名稱獲取類型、根據(jù)名稱獲取別名。一目了然!


          總結(jié):


          這10個方法,很明顯,這是一個典型的工廠模式的工廠接口。


          BeanFactory最常見的實現(xiàn)類為XmlBeanFactory,可以從classpath或文件系統(tǒng)等獲取資源。


          1)File file = new?File("fileSystemConfig.xml");
          Resource resource = new?FileSystemResource(file);
          BeanFactory beanFactory = new?XmlBeanFactory(resource);


          2)Resource resource = new?ClassPathResource("classpath.xml");
          BeanFactory beanFactory = new?XmlBeanFactory(resource);


          XmlBeanFactory可以加載xml的配置文件。假設(shè)我們有一個Car類:


          package spring.ioc.demo1;

          public?class?Car?{

          ????private?String brand;

          ????private?String color;

          ????private?int?maxSpeed;

          ????public?String getBrand() {
          ????????return?brand;
          ????}

          ????public?void?setBrand(String brand) {
          ????????this.brand = brand;
          ????}

          ????public?String getColor() {
          ????????return?color;
          ????}

          ????public?void?setColor(String color) {
          ????????this.color = color;
          ????}

          ????public?int?getMaxSpeed() {
          ????????return?maxSpeed;
          ????}

          ????public?void?setMaxSpeed(int?maxSpeed) {
          ????????this.maxSpeed = maxSpeed;
          ????}
          ????
          ????public?String toString(){
          ????????return?"the car is:"+ getBrand() + ", color is:"?+getColor() +", maxspeed is:"+getMaxSpeed();
          ????}

          ????public?Car() {

          ????}

          ????public?Car(String brand, String color, int?maxSpeed) {
          ????????this.brand = brand;
          ????????this.color = color;
          ????????this.maxSpeed = maxSpeed;
          ????}

          ????public?void?introduce() {
          ????????System.out.println("brand:"?+ brand + ";color:"?+ color + ";maxSpeed:"
          ????????????????+ maxSpeed);
          ????}

          }


          我們通過在applicationContext.xml中配置:


          "car1"?class="spring.ioc.demo1.Car"
          ????????p:brand="spring注入-紅旗001"?
          ????????p:color="spring注入-紫色"?
          ????????p:maxSpeed="520"?/>


          通過XmlBeanFactory實現(xiàn)啟動Spring IoC容器:


          public?static?void?main(String[] args) {

          ?????ResourcePatternResolver resolver = new?PathMatchingResourcePatternResolver();
          ??????Resource res = resolver.getResource("classpath:applicationContext.xml");
          ??????BeanFactory factory = new?XmlBeanFactory(res); //ApplicationContext factory=new ClassPathXmlApplicationContext("applicationContext.xml");
          ????????????
          ???????Car car = factory.getBean("car1",Car.class);
          ???????System.out.println("car對象已經(jīng)初始化完成");
          ???????System.out.println(car.getMaxSpeed());
          }


          1. XmlBeanFactory通過Resource裝載Spring配置信息冰啟動IoC容器,然后就可以通過factory.getBean從IoC容器中獲取Bean了。
          2. 通過BeanFactory啟動IoC容器時,并不會初始化配置文件中定義的Bean,初始化動作發(fā)生在第一個調(diào)用時。
          3. 對于單實例(singleton)的Bean來說,BeanFactory會緩存Bean實例,所以第二次使用getBean時直接從IoC容器緩存中獲取Bean。

          二、ApplicationContext


          如果說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ā)布接口)等。


          三、二者區(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)存空間。當(dāng)應(yīng)用程序配置Bean較多時,程序啟動較慢。


          BeanFacotry延遲加載,如果Bean的某一個屬性沒有注入,BeanFacotry加載后,直至第一次使用調(diào)用getBean方法才會拋出異常;而ApplicationContext則在初始化自身是檢驗,這樣有利于檢查所依賴屬性是否注入;所以通常情況下我們選擇使用 ApplicationContext。

          應(yīng)用上下文則會在上下文啟動后預(yù)載入所有的單實例Bean。通過預(yù)載入單實例bean ,確保當(dāng)你需要的時候,你就不用等待,因為它們已經(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 。


          四、總結(jié)


          作用:

          1. BeanFactory負責(zé)讀取bean配置文檔,管理bean的加載,實例化,維護bean之間的依賴關(guān)系,負責(zé)bean的聲明周期。


          2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,還提供了更完整的框架功能:

          a. 國際化支持
          b. 資源訪問:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”
          c. 事件傳遞:通過實現(xiàn)ApplicationContextAware接口


          3. 常用的獲取ApplicationContext


          FileSystemXmlApplicationContext:從文件系統(tǒng)或者url指定的xml配置文件創(chuàng)建,參數(shù)為配置文件名或文件名數(shù)組,有相對路徑與絕對路徑。


          ApplicationContext factory=new?FileSystemXmlApplicationContext("src/applicationContext.xml");
          ApplicationContext factory=new?FileSystemXmlApplicationContext("E:/Workspaces/MyEclipse 8.5/Hello/src/applicationContext.xml");


          ClassPathXmlApplicationContext:從classpath的xml配置文件創(chuàng)建,可以從jar包中讀取配置文件。ClassPathXmlApplicationContext 編譯路徑總有三種方式:


          ApplicationContext factory = new?ClassPathXmlApplicationContext("classpath:applicationContext.xml");
          ApplicationContext factory = new?ClassPathXmlApplicationContext("applicationContext.xml");
          ApplicationContext factory = new?ClassPathXmlApplicationContext("file:E:/Workspaces/MyEclipse 8.5/Hello/src/applicationContext.xml");


          XmlWebApplicationContext:從web應(yīng)用的根目錄讀取配置文件,需要先在web.xml中配置,可以配置監(jiān)聽器或者servlet來實現(xiàn)



          <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
          listener>



          <servlet>
          <servlet-name>contextservlet-name>
          <servlet-class>org.springframework.web.context.ContextLoaderServletservlet-class>
          <load-on-startup>1load-on-startup>
          servlet>


          這兩種方式都默認配置文件為web-inf/applicationContext.xml,也可使用context-param指定配置文件


          <context-param>
          <param-name>contextConfigLocationparam-name>
          <param-value>/WEB-INF/myApplicationContext.xmlparam-value>
          context-param>



          原文鏈接:cnblogs.com/xiaoxi/p/5846416.html




          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美日韩国产VA在线观看免费 | 九九99免费视频小说热线 | 国产裸身美女网站 | 操逼图片视频 | 久久国产免费娱乐视频 |