亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Spring詳解2.理解IoC容器

Ververica / 2964人閱讀

摘要:目前建議使用與。入?yún)⑹钱?dāng)前正在處理的,是當(dāng)前的配置名,返回的對(duì)象為處理后的。如果,則將放入容器的緩存池中,并返回。和這兩個(gè)接口,一般稱它們的實(shí)現(xiàn)類為后處理器。體系結(jié)構(gòu)讓容器擁有了發(fā)布應(yīng)用上下文事件的功能,包括容器啟動(dòng)事件關(guān)閉事件等。

點(diǎn)擊進(jìn)入我的博客 1 如何理解IoC 1.1 依然是KFC的案例
interface Burger {
    int getPrice();
}
interface Drink {
    int getPrice();
}

class ZingerBurger implements Burger {
    public int getPrice() {
        return 10;
    }
}
class PepsiCola implements Drink {
    public int getPrice() {
        return 5;
    }
}

/**
 * 香辣雞腿堡套餐
 */
class ZingerBurgerCombo {
    private Burger burger = new ZingerBurger();
    private Drink drink = new PepsiCola();

    public int getPrice() {
        return burger.getPrice() + drink.getPrice();
    }
}

上述案例中我們實(shí)現(xiàn)了一個(gè)香辣雞腿堡套餐,在ZingerBurgerCombo中,我們發(fā)現(xiàn)套餐與漢堡、套餐與飲品產(chǎn)生了直接的耦合。要知道肯德基中的套餐是非常多的,這樣需要建立大量不同套餐的類;而且如果該套餐中的百事可樂(lè)如果需要換成其他飲品的話,是不容易改變的。

class KFCCombo {
    private Burger burger;
    private Drink drink;

    public KFCCombo(Burger burger, Drink drink) {
        this.burger = burger;
        this.drink = drink;
    }
}

class KFCWaiter {
    public KFCCombo getZingerBurgerCombo() {
        return new KFCCombo(new ZingerBurger(), new PepsiCola());
    }
    // else combo…
}

為了防止套餐和漢堡、飲品的耦合,我們統(tǒng)一用KFCCombo來(lái)表示所有的套餐組合,引入了一個(gè)新的類KFCWaiter,讓她負(fù)責(zé)所有套餐的裝配。

1.2 控制反轉(zhuǎn)與依賴注入
控制反轉(zhuǎn)IoC

IoC的字面意思是控制反轉(zhuǎn),它包括兩部分的內(nèi)容:

控制:在上述案例中,控制就是選擇套餐中漢堡和飲品的控制權(quán)。

反轉(zhuǎn):反轉(zhuǎn)就是把該控制權(quán)從套餐本身中移除,放到專門的服務(wù)員手中。

對(duì)于Spring來(lái)說(shuō),我們通過(guò)Spring容器管理來(lái)管理和控制Bean的裝配。

依賴注入

由于IoC這個(gè)重要的概念比較晦澀隱諱,Martin Fowler提出了DI(Dependency Injection,依賴注入)的概念用以代替IoC,即讓調(diào)用類對(duì)某一接口實(shí)現(xiàn)類的依賴關(guān)系由第三方(容器或協(xié)作類)注入,以移除調(diào)用類對(duì)某一接口實(shí)現(xiàn)類的依賴。

Spring容器

Spring就是一個(gè)容器,它通過(guò)配置文件或注解描述類和類之間的依賴關(guān)系,自動(dòng)完成類的初始化和依賴注入的工作。讓開(kāi)發(fā)著可以從這些底層實(shí)現(xiàn)類的實(shí)例化、依賴關(guān)系裝配等工作中解脫出來(lái),專注于更有意義的業(yè)務(wù)邏輯開(kāi)發(fā)。

2 IoC的類型

從注入方法上看,IoC可以分為:構(gòu)造函數(shù)注入、屬性注入、接口注入

構(gòu)造函數(shù)注入
class KFCCombo {
    private Burger burger;
    private Drink drink;

    // 在此注入對(duì)應(yīng)的內(nèi)容
    public KFCCombo(Burger burger, Drink drink) {
        this.burger = burger;
        this.drink = drink;
    }
}
屬性注入
class KFCCombo {
    private Burger burger;
    private Drink drink;

    // 在此注入對(duì)應(yīng)的內(nèi)容
    public void setBurger(Burger burger) {
        this.burger = burger;
    }

    // 在此注入對(duì)應(yīng)的內(nèi)容
    public void setDrink(Drink drink) {
        this.drink = drink;
    }
}
接口注入
interface InjectFood {
    void injectBurger(Burger burger);
    void injectDrink(Drink drink);
}

class KFCCombo implements InjectFood {
    private Burger burger;
    private Drink drink;
    
    // 在此注入對(duì)應(yīng)的內(nèi)容
    public void injectBurger(Burger burger) {
        this.burger = burger; 
    }
    // 在此注入對(duì)應(yīng)的內(nèi)容
    public void injectDrink(Drink drink) {
        this.drink = drink;
    }
}

接口注入和屬性注入并無(wú)本質(zhì)的區(qū)別,而且還增加了一個(gè)額外的接口導(dǎo)致代碼增加,因此不推薦該方式。

3 資源訪問(wèn)

JDK提供的訪問(wèn)資源的類(如java.net.URL、File等)并不能很好地滿足各種底層資源的訪問(wèn)需求,比如缺少?gòu)念惵窂交蛘遅eb容器上下文中獲取資源的操作類。因此,Spring提供了Resource接口,并由此裝載各種資源,包括配置文件、國(guó)際化屬性文件等資源。

3.1 Resource類圖

WritableResource:可寫資源接口,Spring3.1新增的接口,有2個(gè)實(shí)現(xiàn)類:FileSystemResourcePathResource。

ByteArrayResource:二進(jìn)制數(shù)組表示的資源,二進(jìn)制數(shù)組資源可以在內(nèi)存中通過(guò)程序構(gòu)造。

ClassPathResource:類路徑下的資源,資源以相對(duì)于類路徑的方式表示。

FileSystemResouce:文件系統(tǒng)資源,資源以文件系統(tǒng)路徑的方式表示。

InputStreamResource:以輸入流返回標(biāo)識(shí)的資源

ServletContextResource:為訪問(wèn)Web容器上下文中的資源而設(shè)計(jì)的類,負(fù)責(zé)以相對(duì)于Web應(yīng)用根目錄的路徑來(lái)加載資源。支持以流和URL的形式訪問(wèn),在war包解包的情況下,也可以通過(guò)File方式訪問(wèn)。 該類還可以直接從JAR包中訪問(wèn)資源。

UrlResource:封裝了java.net.URL,它使用戶能夠訪問(wèn)任何可以通過(guò)URL表示的資源,如文件系統(tǒng)的資源、HTTP資源、FTP資源

PathResource:Spring 4.0提供的讀取資源文件的新類。PathResource封裝了java.net.URL、java.nio.file.Path、文件系統(tǒng)資源,它使用戶能夠訪問(wèn)任何可以通過(guò)URL、Path、系統(tǒng)文件路徑標(biāo)識(shí)的資源,如文件系統(tǒng)的資源、HTTP資源、FTP資源

3.2 資源加載

為了訪問(wèn)不同類型的資源,Resource接口下提供了不同的子類,這造成了使用上的不便。Spring提供了一個(gè)強(qiáng)大的加載資源的方式,在不顯示使用Resource實(shí)現(xiàn)類的情況下,僅通過(guò)不同資源地址的特殊標(biāo)示就可以訪問(wèn)對(duì)應(yīng)的資源。

地址前綴 實(shí)例 釋義
classpath: classpath:com/ankeetc/spring/Main.class 從類不經(jīng)中加載資源,classpath: 和 classpath:/ 是等價(jià)的,都是相對(duì)于類的根路徑,資源文件可以在標(biāo)準(zhǔn)的文件系統(tǒng)中,也可以在jar或者zip的類包中
file: file:/Users/zhengzhaoxi/.gitconfig 使用UrlResource從文件系統(tǒng)目錄中裝載資源,可以采用絕對(duì)路徑或者相對(duì)路徑
http:// http://spiderlucas.github.io/... 使用UrlResource從web服務(wù)器中加載資源
ftp:// ftp://spiderlucas.github.io/atom.xml 使用UrlResource從FTP服務(wù)器中裝載資源
沒(méi)有前綴 com/ankeetc/spring/Main.class 根據(jù)ApplicationContext的具體實(shí)現(xiàn)類采用對(duì)應(yīng)類型的Resource
classpath:與classpath*:

假設(shè)有多個(gè)Jar包或者文件系統(tǒng)類路徑下?lián)碛幸粋€(gè)相同包名(如com.ankeetc):

classpath:只會(huì)在第一個(gè)加載的com.ankeetc包的類路徑下查找

classpath*:會(huì)掃描到所有的這些JAR包及類路徑下出現(xiàn)的com.ankeetc類路徑。

這對(duì)于分模塊打包的應(yīng)用非常有用,假設(shè)一個(gè)應(yīng)用分為2個(gè)模塊,每一個(gè)模塊對(duì)應(yīng)一個(gè)配置文件,分別為module1.yaml 、module2.yaml,都放在了com.ankeetc的目錄下,每個(gè)模塊多帶帶打成JAR包??梢允褂?classpath*:com/ankeetc/module*.xml加載所有模塊的配置文件。

Ant風(fēng)格的資源地址通配符

? 匹配文件名中的一個(gè)字符

* 匹配文件名中的任意字符

** 匹配多層路徑

資源加載器

ResourceLoader接口僅有一個(gè)getResource(String loacation)方法,可以根據(jù)一個(gè)資源地址加載文件資源。不過(guò),資源地址僅支持帶資源類型前綴的表達(dá)式,不支持Ant風(fēng)格的資源路徑表達(dá)式。

ResourcePatternResolver擴(kuò)展ResourceLoader接口,定義了一個(gè)新的接口方法getResource(String locationPattern),改方法支持帶資源類型前綴及Ant風(fēng)格的資源路徑表達(dá)式。

PathMatchingResourcePatternResolver是Spring提供的標(biāo)準(zhǔn)實(shí)現(xiàn)類。

4 BeanFactory

BeanFactory是Spring框架最核心的接口,它提供了高級(jí)IoC的配置機(jī)制。我們一般稱BeanFactory為IoC容器。

BeanFactory是Spring框架等基礎(chǔ)設(shè)施,面向Spring本身。

BeanFactory是一個(gè)類工廠,可以創(chuàng)建并管理各種類的對(duì)象。

所有可以被Spring容器實(shí)例化并管理的Java類都可以成為Bean。

BeanFactory主要方法就是getBean(String beanName);

BeanFactory啟動(dòng)IoC容器時(shí),并不會(huì)初始化配置文件中定義的Bean,初始化動(dòng)作在第一個(gè)調(diào)用時(shí)產(chǎn)生。

對(duì)于單實(shí)例的Bean來(lái)說(shuō),BeanFactory會(huì)緩存Bean實(shí)例,在第二次使用geBean()獲取Bean時(shí),將直接從IoC容器的緩存中獲取Bean實(shí)例。

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

BeanFactory:BeanFactory接口位于類結(jié)構(gòu)樹(shù)的頂端,它最主要的方法就是getBean(String beanName) ,該方法從容器中返回特定名稱的Bean,BeanFactory的功能通過(guò)其他接口而得到不斷擴(kuò)展。

ListableBeanFactory:該接口定義了訪問(wèn)容器中Bean基本信息的若干方法,如:查看 Bean 的個(gè)數(shù)、獲取某一類型Bean的配置名、或查看容器中是否包含某一個(gè)Bean。

HierarhicalBeanFactory:父子級(jí)聯(lián) IoC 容器的接口,子容器可以通過(guò)接口方法訪問(wèn)父容器。

ConfigurableBeanFactory:該接口增強(qiáng)了IoC容器的可定制性,它定義了設(shè)置類裝載器、屬性 編輯器、容器初始化后置處理器等方法。

AutowireCapableBeanFactory:定義了將容器中的Bean按某種規(guī)則(如:按名稱匹配、按類型匹配)進(jìn)行自動(dòng)裝配的方法。

SingletonBeanFactory:定義了允許在運(yùn)行期間向容器注冊(cè)單實(shí)例Bean的方法。

BeanDefinitionRegistry:Spring配置文件中每一個(gè)Bean節(jié)點(diǎn)元素在Spring容器里都通過(guò)一個(gè) BeanDefinition對(duì)象表示,它描述了Bean的配置信息。而B(niǎo)eanDefinitionRegistry接口提供了向容器手工注冊(cè)BeanDefinition對(duì)象的方法。

4.2 初始化BeanFactory

BeanFactory有多種實(shí)現(xiàn),最常用的是 XmlBeanFactory,但在Spring 3.2時(shí)已被廢棄。目前建議使用XmlBeanDefinitionReader與DefaultListableBeanFactory。



    
    public static void main(String[] args) throws Exception {
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("beans.xml");

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(resource);

        beanFactory.getBean("");
    }
4.3 BeanFactory中Bean的生命周期

當(dāng)調(diào)用者通過(guò)getBean()向容器請(qǐng)求一個(gè)Bean時(shí),如果容器注冊(cè)了InstantiationAwareBeanPostProcessor接口,則在實(shí)例化Bean之前,調(diào)用postProcessBeforeInstantiation()方法。

根據(jù)配置調(diào)用構(gòu)造方法或者工廠方法實(shí)例化Bean。

調(diào)用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()。

調(diào)用InstantiationAwareBeanPostProcessor#postProcessPropertyValues()方法。

設(shè)置屬性值。

如果Bean實(shí)現(xiàn)了BeanNameAware接口,則將調(diào)用BeanNameAware#setBeanName()接口方法,將配置文件中該Bean對(duì)應(yīng)的名稱設(shè)置到Bean中。

如果Bean實(shí)現(xiàn)了BeanFactoryAware接口,將調(diào)用BeanFactoryAware#setBeanFactory()接口方法。

如果容器注冊(cè)了BeanPostProcessor接口,將調(diào)用BeanPostProcessor#postProcessBeforeInitialization()方法。入?yún)ean是當(dāng)前正在處理的Bean,BeanName是當(dāng)前Bean的配置名,返回的對(duì)象為處理后的Bean。BeanPostProcessor在Spring框架中占有重要的地位,為容器提供對(duì)Bean進(jìn)行后續(xù)加工處理的切入點(diǎn),AOP、動(dòng)態(tài)代理都通過(guò)BeanPostProcessor來(lái)實(shí)現(xiàn)。

如果Bean實(shí)現(xiàn)了InitializingBean接口,則將調(diào)用InitializingBean#afterPropertiesSet()方法。

如果中定義了init-method初始化方法,則執(zhí)行這個(gè)方法。

調(diào)用BeanPostProcessor#postProcessAfterInitialization()方法再次加工Bean。

如果中指定了Bean的作用范圍為scope="prototype",則將Bean返回給調(diào)用者,Spring不再管理這個(gè)Bean的生命周期。如果scope="singleton",則將Bean放入Spring IoC容器的緩存池中,并返回Bean。

對(duì)于scope="singleton"的Bean,當(dāng)容器關(guān)閉時(shí),將觸發(fā)Spring對(duì)Bean的后續(xù)生命周期的管理工作。如果Bean實(shí)現(xiàn)了DisposableBean接口,將調(diào)用DisposableBean#destroy()方法。

對(duì)于`scope="singleton"的Bean,如果通過(guò)的destroy-method屬性指定了Bean的銷毀方法,那么Spring將執(zhí)行這個(gè)方法。

Bean方法的分類

Bean自身的方法:構(gòu)造方法、Setter設(shè)置屬性值、init-method、destroy-method。

Bean級(jí)生命周期接口方法:如上圖中藍(lán)色的部分。BeanNameAware、BeanFactoryAware、InitializingBean、DisposableBean,這些由Bean本身直接實(shí)現(xiàn)。

容器級(jí)生命周期接口方法:如上圖中的紅色的部分。InstantiationAwareBeanPostProcessor和BeanPostProcessor這兩個(gè)接口,一般稱它們的實(shí)現(xiàn)類為后處理器。后處理器接口不由Bean本身實(shí)現(xiàn),實(shí)現(xiàn)類以容器附加裝置的形式注冊(cè)到Spring容器中。當(dāng)Spring容器創(chuàng)建任何Bean的時(shí)候,這些后處理器都會(huì)起作用,所以這些后處理器的影響是全局的。如果需要多個(gè)后處理器,可以同時(shí)實(shí)現(xiàn)Ordered接口,容器將按照特定的順序依此調(diào)用這些后處理器。

工廠后處理器接口方法:AspectJWeavingEnabler、CustomAutowireConfigurer、ConfigurationClassPostProcessor等方法,工廠后處理器也是容器級(jí)的,在應(yīng)用上下文裝配配置文件后立即使用。

4.4 BeanFactory生命周期案例
public class Main {
    public static void main(String[] args) {
        Resource resource = new PathMatchingResourcePatternResolver().getResource("classpath:beans.xml");

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(resource);

        beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() {
            public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
                System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()");
                return null;
            }

            public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
                System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()");
                return true;
            }

            public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
                System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues()");
                return pvs;
            }

            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                System.out.println("BeanPostProcessor.postProcessBeforeInitialization()");
                return bean;
            }

            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                System.out.println("BeanPostProcessor.postProcessAfterInitialization()");
                return bean;
            }
        });

        MyBean myBean = beanFactory.getBean("myBean", MyBean.class);
        beanFactory.destroySingletons();
    }
}

class MyBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    private String prop;

    public MyBean() {
        System.out.println("MyBean:構(gòu)造方法");
    }

    public String getProp() {
        System.out.println("MyBean:get方法");
        return prop;
    }

    public void setProp(String prop) {
        System.out.println("MyBean:set方法");
        this.prop = prop;
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("MyBean:BeanFactoryAware.setBeanFactory()");
    }

    public void setBeanName(String name) {
        System.out.println("MyBean:BeanNameAware.setBeanName()");
    }

    public void destroy() throws Exception {
        System.out.println("MyBean:DisposableBean.destroy()");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("MyBean:InitializingBean.afterPropertiesSet()");
    }

    // 配置文件中init-method
    public void myInit() {
        System.out.println("MyBean:myInit()");
    }

    // 配置文件中destroy-method
    public void myDestroy() {
        System.out.println("MyBean:myDestroy()");
    }
}


    
        
    
4.5 關(guān)于Bean生命周期接口的探討

Bean生命周期帶來(lái)的耦合:通過(guò)實(shí)現(xiàn)Spring的Bean生命周期接口對(duì)Bean進(jìn)行額外控制,雖然讓Bean具有了更細(xì)致的生命周期階段,但也帶來(lái)了一個(gè)問(wèn)題,Bean和Spring框架緊密綁定在一起了,這和Spring一直推崇的“不對(duì)應(yīng)用程序類作任何限制”的理念是相悖的。業(yè)務(wù)類本應(yīng)該完全POJO化,只實(shí)現(xiàn)自己的業(yè)務(wù)接口,不需要和某個(gè)特定框架(包括Spring框架)的接口關(guān)聯(lián)。

init-method和destroy-method:可以通過(guò)init-methoddestroy-method屬性配置方式為Bean指定初始化和銷毀的方法,采用這種方式對(duì)Bean生命周期的控制效果和通過(guò)實(shí)現(xiàn)InitializingBeanDisposableBean接口所達(dá)到的效果是完全相同的,而且達(dá)到了框架解耦的目的。

BeanPostProcessor:BeanPostProcessor接口不需要Bean去繼承它,可以像插件一樣注冊(cè)到Spring容器中,為容器提供額外功能。

5 ApplicationContext 5.1 Application體系結(jié)構(gòu)

ApplicationEventPublisher:讓容器擁有了發(fā)布應(yīng)用上下文事件的功能,包括容器啟動(dòng)事件 、關(guān)閉事件等。實(shí)現(xiàn)了ApplicationListener事件監(jiān)聽(tīng)接口的Bean可以接收到容器事件,并對(duì)容器事件進(jìn)行響應(yīng)處理。在ApplicationContext抽象實(shí)現(xiàn)類AbstractApplicationContext中存在一個(gè) ApplicationEventMulticaster,它負(fù)責(zé)保存所有的監(jiān)聽(tīng)器,以便在容器產(chǎn)生上下文事件時(shí)通知這些事件監(jiān)聽(tīng)者。

MessageSource:為容器提供了i18n國(guó)際化信息訪問(wèn)的功能。

ResourcePatternResolver:所有ApplicationContext實(shí)現(xiàn)類都實(shí)現(xiàn)了類似于PathMatchingResourcePatternResolver的功能,可以通過(guò)帶前綴 Ant 風(fēng)格的資源類文件路徑來(lái)裝載Spring的配置文件。

LifeCycle:它提供了start()和stop()兩個(gè)方法,主要用于控制異步處理過(guò)程。在具體使用時(shí),該接口同時(shí)被ApplicationContext實(shí)現(xiàn)及具體Bean實(shí)現(xiàn),ApplicationContext會(huì)將start/stop的信息傳遞給容器中所有實(shí)現(xiàn)了該接口的Bean,以達(dá)到管理和控制JMX、任務(wù)調(diào)度等目的。

ConfigurableApplicationContext:它擴(kuò)展了ApplicationContext,讓ApplicationContext具有啟動(dòng)、刷新和關(guān)閉應(yīng)用上下文的能力。上下文關(guān)閉時(shí),調(diào)用 refresh()即可啟動(dòng)上下文;如果已經(jīng)啟動(dòng),則調(diào)用refresh()可清除緩存并重新加載配置信息;調(diào)用close()可關(guān)閉應(yīng)用上下文。

5.2 初始化ApplicationContext

ClassPathXmlApplicationContext:從類路徑中加載XML配置文件,也可以顯示的使用帶資源類型前綴的路徑。

FileSystemXmlApplicationContext:從文件系統(tǒng)路徑下加載XML配置文件,也可以顯示的使用帶資源類型前綴的路徑。

AnnotationConfigApplicationContext:一個(gè)標(biāo)注@Configuration注解的POJO即可提供Spring所需的Bean配置信息。

GenericGroovyApplicationContext:從Groovy配置中提取Bean。

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext classPathXmlApplicationContext =
                new ClassPathXmlApplicationContext("beans.xml");
        FileSystemXmlApplicationContext fileSystemXmlApplicationContext =
                new FileSystemXmlApplicationContext("file:/Users/zhengzhaoxi/Git/spring/src/main/resources/beans.xml");
        AnnotationConfigApplicationContext annotationConfigApplicationContext =
                new AnnotationConfigApplicationContext(Config.class);
    }
5.3 WebApplicationContext體系結(jié)構(gòu)

見(jiàn)后續(xù)章節(jié)

5.4 ApplicationContext中Bean的生命周期

不同點(diǎn)

Bean在ApplicationContext和BeanFactory中生命周期類似,但有以下不同點(diǎn)

如果Bean實(shí)現(xiàn)了ApplicationContextAware接口,則會(huì)增加一個(gè)調(diào)用該接口方法的ApplicationContextAware.setApplicationContext的方法。

如果在配置文件中生命了工廠后處理器接口BeanFactoryPostProcessor的實(shí)現(xiàn)類,則應(yīng)用上下文在裝在配置文件之后、初始化Bean實(shí)例之前會(huì)調(diào)用這些BeanFactoryPostProcessor對(duì)配置信息進(jìn)行加工處理。Spring提供了多個(gè)工廠容器,如CustomEditorConfigure、PropertyPlaceholderConfigurer等。工廠后處理器是容器級(jí)的,只在應(yīng)用上下文初始化時(shí)調(diào)用一次,其目的是完成一些配置文件加工處理工作。

ApplicationContext可以利用Java反射機(jī)制自動(dòng)識(shí)別出配置文件中定義的BeanPostProcessor、InstantiationAwareBeanPostProcessorBeanFactoryPostProcessor,并自動(dòng)將它們注冊(cè)到應(yīng)用上下文中(如下所示);而B(niǎo)eanFactory需要通過(guò)手工調(diào)用addBeanPostProcessor()方法注冊(cè)。



    
        
    

    
    

    
    
6 BeanFactory與ApplicationContext區(qū)別

一般稱BeanFactory為IoC容器:Bean工廠(com.springframework.beans.factory.BeanFactory)是Spring框架中最核心的接口,它提供了高級(jí) IoC 的配置機(jī)制 。BeanFactory使管理不同類型的Java對(duì)象成為可能。BeanFactory是Spring框架的基礎(chǔ)設(shè)施,面向Spring本身。

一般稱ApplicationContext為應(yīng)用上下文或Spring容器:應(yīng)用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory基礎(chǔ)之上,提供了更多面向應(yīng)用的功能,它提供了國(guó)際化支持和框架事件體系,更易于創(chuàng)建實(shí)際應(yīng)用 。 ApplicationContext 面向使用 Spring 框架的開(kāi)發(fā)者,幾乎所有的應(yīng)用場(chǎng)合都可以直接使用 ApplicationContext。

BeanFactory在初始化容器的時(shí)候,并未實(shí)例化Bean,直到第一次訪問(wèn)某個(gè)Bean時(shí)才實(shí)例化Bean;ApplicationContext在初始化應(yīng)用上下文的時(shí)候就實(shí)例化全部單實(shí)例Bean。

ApplicationContext可以利用Java反射機(jī)制自動(dòng)識(shí)別出配置文件中定義的BeanPostProcessor、InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor,并自動(dòng)將它們注冊(cè)到應(yīng)用上下文中;而B(niǎo)eanFactory需要通過(guò)手工調(diào)用addBeanPostProcessor()方法注冊(cè)。

7 父子容器

通過(guò)HierarchicalBeanFactory接口,Spring的IoC容器可以建立父子層級(jí)關(guān)聯(lián)的容器體系,子容器可以訪問(wèn)父容器中的 Bean,但父容器不能訪問(wèn)子容器的Bean。

在容器內(nèi),Bean的id必須是唯一的,但子容器可以擁有一個(gè)和父容器id相同的 Bean。

父子容器層級(jí)體系增強(qiáng)了Spring容器架構(gòu)的擴(kuò)展性和靈活性,因此第三方可以通過(guò)編程的方式,為一個(gè)已經(jīng)存在的容器添加一個(gè)或多個(gè)特殊用途的子容器,以提供一些額外的功能。

Spring使用父子容器的特性實(shí)現(xiàn)了很多能力,比如在Spring MVC中,展現(xiàn)層Bean位于一個(gè)子容器中,而業(yè)務(wù)層和持久層的Bean位于父容器中。 這樣展現(xiàn)層Bean就可以引用業(yè)務(wù)層和持久層的Bean,而業(yè)務(wù)層和持久層的Bean則看不到展現(xiàn)層的Bean。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72862.html

相關(guān)文章

  • Java深入-框架技巧

    摘要:從使用到原理學(xué)習(xí)線程池關(guān)于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實(shí)現(xiàn)在軟件開(kāi)發(fā)中,分散于應(yīng)用中多出的功能被稱為橫切關(guān)注點(diǎn)如事務(wù)安全緩存等。 Java 程序媛手把手教你設(shè)計(jì)模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經(jīng)風(fēng)雨慢慢變老,回首走過(guò)的點(diǎn)點(diǎn)滴滴,依然清楚的記得當(dāng)初愛(ài)情萌芽的模樣…… Java 進(jìn)階面試問(wèn)題列表 -...

    chengtao1633 評(píng)論0 收藏0
  • SpringBoot自動(dòng)配置原理

    摘要:開(kāi)啟自動(dòng)配置功能后文詳解這個(gè)注解,學(xué)過(guò)的同學(xué)應(yīng)該對(duì)它不會(huì)陌生,就是掃描注解,默認(rèn)是掃描當(dāng)前類下的。簡(jiǎn)單來(lái)說(shuō),這個(gè)注解可以幫助我們自動(dòng)載入應(yīng)用程序所需要的所有默認(rèn)配置。簡(jiǎn)單理解這二者掃描的對(duì)象是不一樣的。 前言 只有光頭才能變強(qiáng)。 文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/ZhongFuCheng3y/3y 回顧前面Spring的文章(以學(xué)習(xí)...

    Rainie 評(píng)論0 收藏0
  • Spring IoC學(xué)習(xí)總結(jié)

    摘要:學(xué)習(xí)總結(jié)學(xué)習(xí)整理的一些筆記,很簡(jiǎn)單。大部分認(rèn)為和只是不同的叫法而已。依賴注入的兩種方式和注解使用注釋驅(qū)動(dòng)的功能源碼剖析 Spring IoC學(xué)習(xí)總結(jié) 學(xué)習(xí)spring Ioc整理的一些筆記,很簡(jiǎn)單。分享給大家。 IoC 基本概念 在這之前,我們先記住一句話。好萊塢原則:Dont call us, we will call you.其實(shí)這句話很恰當(dāng)?shù)匦稳萘朔崔D(zhuǎn)的意味;Ioc, Inve...

    silencezwm 評(píng)論0 收藏0
  • Spring框架學(xué)習(xí)筆記(一):官方文檔介紹,IoC與AOP概念學(xué)習(xí)

    摘要:構(gòu)造函數(shù)注入通過(guò)調(diào)用類的構(gòu)造函數(shù),將接口實(shí)現(xiàn)類通過(guò)構(gòu)造函數(shù)變量傳入。而在中,其使用橫切技術(shù),將這類代碼從原屬的封裝對(duì)象中提取出來(lái),封裝到一個(gè)可重用模塊中,稱為。 最近實(shí)習(xí)用到Spring的開(kāi)發(fā)框架,但是之前沒(méi)有接觸過(guò),因此希望利用網(wǎng)上的資源來(lái)學(xué)習(xí)以下。 Spring官方給出了非常全面的介紹,非常適合我這種完全的小白……在這一系列學(xué)習(xí)中,我閱讀的主要資源是5.1.2 Reference ...

    mindwind 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<