ApplicationContext和XmlBeanFactory有哪些區(qū)別

這篇文章主要講解了“ApplicationContext和XmlBeanFactory有哪些區(qū)別”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“ApplicationContext和XmlBeanFactory有哪些區(qū)別”吧!

成都創(chuàng)新互聯(lián)擁有一支富有激情的企業(yè)網(wǎng)站制作團隊,在互聯(lián)網(wǎng)網(wǎng)站建設行業(yè)深耕十年,專業(yè)且經(jīng)驗豐富。十年網(wǎng)站優(yōu)化營銷經(jīng)驗,我們已為1000+中小企業(yè)提供了網(wǎng)站制作、成都做網(wǎng)站解決方案,按需策劃設計,設計滿意,售后服務無憂。所有客戶皆提供一年免費網(wǎng)站維護!

ApplicationContext和XmlBeanFactory的區(qū)別

在ApplicationContext的源碼解析中,這些推測還能使用嗎?答案是可以的。之前我們聊過IOC容器的設計與實現(xiàn),無非就是兩個系列,一個BeanFactory,一個ApplicationContext。那么我們之前看的XmlBeanFactory屬于哪一種類呢?先來看一下XmlBeanFactory的類圖 ApplicationContext和XmlBeanFactory有哪些區(qū)別

XmlBeanFactory繼承體系是 XmlBeanFactory -> DefaultListableBeanFactory -> AbstractAutowireCapableBeanFactory -> AbstractBeanFactory -> FactoryBeanRegistrySupport -> DefaultSingletonBeanRegistry -> SimpleAliasRegistry -> AliasRegistry

但是請注意:XmlBeanFactory是在DefaultListableBeanFactory的基礎上做擴展的。其實最終還是實現(xiàn)了BeanFactory接口。而我們的ApplicationContext,它是做為一種容器的高級形態(tài)存在。應用上下文,在簡單的容器上增加了許多其他的特性。為什么這么說呢?我們來看看ApplicationContext的類圖。

ApplicationContext和XmlBeanFactory有哪些區(qū)別

不難發(fā)現(xiàn)ApplicationContext其實也是實現(xiàn)了BeanFactory,但是這里可以明顯的看到,ApplicationContext做了更多的支持。

BeanFactory

BeanFactory是Spring最核心的所在,很多面試題問Spring是什么?其實就可以直接回答:Spring其實就是一個BeanFactory的巨大封裝,當然好像有點片面,BeanFactory確確實實是Spring最核心的內(nèi)容。

BeanFactory提供的是最基本的IOC容器的功能,關于這些功能,我們可以來讀一下他的源碼

String FACTORY_BEAN_PREFIX = "&";

/**
 * 根據(jù)名稱獲取bean
 */
Object getBean(String name) throws BeansException;

<T> T getBean(String name, Class<T> requiredType) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

/**
 * 是否包含bean
 */
boolean containsBean(String name);

/**
 * 查詢bean是否是Singleton類型
 */
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/**
 * 查詢bean是否是Prototype類型
 */
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/**
 * 查詢bean的class類型是否是特定的class類型
 */
boolean isTypeMatch(String name, Class<?> targetType)
        throws NoSuchBeanDefinitionException;

/**
 * 查詢bean的class類型
 */
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

/**
 * 查詢bean的所有別名
 */
String[] getAliases(String name);

其實它的代碼并不多,但是它提供了使用IOC容器的規(guī)范。理解這些呢,有助于我們理解ApplicationContext,我們可以直接認為BeanFactory是一種簡單的容器形式,而ApplicationContext它是一種高級的容器形式。

到這里,其實我們已經(jīng)看到XmlBeanFactory和ApplicationContext的一些區(qū)別了。但是這里其實不是那么的明顯。我們不妨再來看看那ApplicationContext它的實現(xiàn)類ClassPathXmlApplicationContext,也就是我們代碼里面用的。它的一個源碼和XmlBeanFactory的區(qū)別在哪

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
        this.refresh();
    }
}

它的初始化在不斷的調(diào)用super(parent),但是refresh()方法完成了容器的初始化。

refresh()方法的實現(xiàn)代碼如下

public void refresh() throws BeansException, IllegalStateException {
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh(); // 準備工作
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 獲取ConfigurableListableBeanFactory最終的目的是DefaultListableBeanFactory
        this.prepareBeanFactory(beanFactory); // 準備bean工廠

        try {
            this.postProcessBeanFactory(beanFactory); // 一個空的實現(xiàn),注意這里的spring版本號為:5.3x
            this.invokeBeanFactoryPostProcessors(beanFactory); // 注冊bean的工廠
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource(); // Spring 從所有的 @Bean 定義中抽取出來了 BeanPostProcessor,然后都注冊進 beanPostProcessors,等待后面的的順序調(diào)用 注冊BeanPostProcessor
            this.initApplicationEventMulticaster(); // 初始化事件監(jiān)聽多路廣播器
            this.onRefresh(); // 一個空的實現(xiàn)
            this.registerListeners(); // 注冊監(jiān)聽器
            this.finishBeanFactoryInitialization(beanFactory); // 到了spring加載流程最復雜的一步,開始實例化所有的bd
            this.finishRefresh();// 刷新完成工作
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

方法從總體上看 還算比較清晰 用幾個大的方法高度概括了refresh()做了些什么。后面我們會詳細來解讀這些流程,這里僅做一個總結。

到這里位置,我們看到了ClassPathXmlApplicationContext的一個流程,和我們的XmlBeanFactory的區(qū)別相當?shù)拇?,在我們之前的推測中,他應該先去加載xml,其實這里也做了,只是隱藏的比較深,在這個加載流程的第二部的具體內(nèi)容里面,我們這里貼一下核心代碼

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

this.refreshBeanFactory();

this.loadBeanDefinitions(beanFactory);

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    this.initBeanDefinitionReader(beanDefinitionReader);
    this.loadBeanDefinitions(beanDefinitionReader);
}

其實bean的初始化和容器的初始化也在這個流程里面全部提現(xiàn)了,這個我們后面再講,但是從我們總結的內(nèi)容來看,其實和我們的推測是大差不差的,只是多了很多其他的東西而已。多出來的這些東西也正是我們兩種容器實現(xiàn)的區(qū)別所在。

總結:

  • BeanFactory的基本實現(xiàn)提供了基本的IOC容器,ApplicaitonContext以高級形態(tài)出現(xiàn),增加了很多附加功能。

  • XmlBeanFactory是我們BeanFactory一種最基本應用

  • XmlBeanFactory和ClassPathXmlApplicationContext都具備我們推測的流程,但是實現(xiàn)有所不同,而且具體流程上,兩個區(qū)別很大

感謝各位的閱讀,以上就是“ApplicationContext和XmlBeanFactory有哪些區(qū)別”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對ApplicationContext和XmlBeanFactory有哪些區(qū)別這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!

新聞名稱:ApplicationContext和XmlBeanFactory有哪些區(qū)別
本文URL:http://muchs.cn/article24/ghidje.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護網(wǎng)頁設計公司、網(wǎng)站導航、企業(yè)網(wǎng)站制作微信公眾號手機網(wǎng)站建設

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設