国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring源碼閱讀——ClassPathXmlApplicationContext(一)

taowen / 1256人閱讀

摘要:的繼承關(guān)系繼承了,實(shí)現(xiàn)了接口。是所有容器的頂級(jí)接口,中所有容器都是基于的。方法創(chuàng)建一個(gè)新的容器。在本方法中,最重要的是,調(diào)用這個(gè)方法解析配置文件,注冊(cè)。

ClassPathXmlApplicationContext的繼承關(guān)系

ClassPathXmlApplicationContext繼承了AbstractXmlApplicationContext,實(shí)現(xiàn)了ApplicationContext接口。BeanFactory是所有容器的頂級(jí)接口,spring中所有容器都是基于BeanFactory的。ClassPathXmlApplicationContext繼承關(guān)系如下圖:

創(chuàng)建ClassPathXmlApplicationContext實(shí)例

ClassPathXmlApplicationContext中有多個(gè)構(gòu)造方法,最終都通過如下的構(gòu)造方法初始化容器:

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

其中,refresh()方法完成了容器的初始化。

refresh()方法的實(shí)現(xiàn)分析

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

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 上下文刷新的準(zhǔn)備工作,完成一下工作:
            //1、設(shè)置啟動(dòng)時(shí)間、是否關(guān)閉和是否激活
            //2、在上下文中初始化任何占位符屬性資源
            //3、驗(yàn)證標(biāo)記為必需的屬性文件是可解析的
            prepareRefresh();

            // 創(chuàng)建DefaultListableBeanFactory實(shí)例,解析xml配置文件,注冊(cè)bean
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //對(duì)BeanFactory進(jìn)行各種功能填充
            //在此方法中,增加的支持@Qualifier與@Autowired這兩個(gè)注解
            prepareBeanFactory(beanFactory);

            try {
                // 由子類實(shí)現(xiàn),可進(jìn)行自定義擴(kuò)展
                postProcessBeanFactory(beanFactory);

                // 激活BeanFactory的處理器
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // 初始化message資源
                initMessageSource();

                // 為這個(gè)context初始化一個(gè)事件廣播器
                initApplicationEventMulticaster();

                // 由子類實(shí)現(xiàn),初始化其他bean
                onRefresh();

                // 注冊(cè)已實(shí)現(xiàn)ApplicationListener接口的Bean
                registerListeners();

                // 實(shí)例化所有非延遲初始化的單例模式bean
                finishBeanFactoryInitialization(beanFactory);

                // 完成刷新過程,通知生命周期處理器lifecycleProcessor刷新過程,同時(shí)發(fā)出ContextRefreshEvent通知監(jiān)聽者
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset "active" flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring"s core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
obtainFreshBeanFactory()方法的實(shí)現(xiàn)

此方法主要作用是創(chuàng)建DefaultListableBeanFactory實(shí)例,解析xml配置文件,注冊(cè)bean。內(nèi)部調(diào)用了調(diào)用了AbstractRefreshableApplicationContext類的refreshBeanFactory()方法創(chuàng)建bean工廠。refreshBeanFactory()方法實(shí)現(xiàn)如下:

protected final void refreshBeanFactory() throws BeansException {
        //如果beanfactory存在,銷毀所以bean和關(guān)閉beanfactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            //定義beanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            //將bean解析為BeanDefinition
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

refreshBeanFactory()方法中,首先判斷是否存在beanfactory,如果存在,銷毀所有Bean,關(guān)閉beanfactory。createBeanFactory()方法創(chuàng)建一個(gè)新的容器。在本方法中,最重要的是loadBeanDefinitions(beanFactory),調(diào)用這個(gè)方法解析xml配置文件,注冊(cè)bean。

loadBeanDefinitions(beanFactory)方法的實(shí)現(xiàn)如下
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 根據(jù)給定的BeanFactory創(chuàng)建一個(gè)新的 XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 根據(jù)上下文配置bean definition reader
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        initBeanDefinitionReader(beanDefinitionReader);
        //通過beanDefinitionReader解析xml配置文件,注冊(cè)bean
        loadBeanDefinitions(beanDefinitionReader);
    }

在XmlBeanDefinitionReader中實(shí)現(xiàn)了loadBeanDefinitions(beanDefinitionReader)方法,代碼如下:

//省略了異常處理相關(guān)代碼,主要邏輯如下
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        //從encodedResource中得到InputSource和Resource
        Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
        InputStream inputStream = encodedResource.getResource().getInputStream();
        InputSource inputSource = new InputSource(inputStream);
        if (encodedResource.getEncoding() != null) {
            inputSource.setEncoding(encodedResource.getEncoding());
        }
         //調(diào)用此方法加載BeanDefinition
        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }

doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,從資源文件中讀取Document,并且調(diào)用registerBeanDefinitions(doc, resource)注冊(cè)BeanDefinition,省略無關(guān)代碼,實(shí)現(xiàn)如下:

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {
            //從resource中讀取得到Document
            Document doc = doLoadDocument(inputSource, resource);
            //注冊(cè)BeanDefinition
            return registerBeanDefinitions(doc, resource);
        }
        catch (BeanDefinitionStoreException ex) {
            throw ex;
        }
}

在registerBeanDefinitions(doc, resource)方法中,BeanDefinition的注冊(cè)時(shí)委托給BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法進(jìn)行注冊(cè)的。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/69654.html

相關(guān)文章

  • Spring源碼閱讀——ClassPathXmlApplicationContext(四)

    摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫一個(gè)自定義標(biāo)簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...

    silenceboy 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(四)

    摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫一個(gè)自定義標(biāo)簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...

    wmui 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(四)

    摘要:在的方法中,遍歷每一個(gè)節(jié)點(diǎn),判斷是否為默認(rèn)命名空間中的節(jié)點(diǎn),如果是非默認(rèn)命名空間的,調(diào)用方法進(jìn)行處理。在學(xué)習(xí)自定義標(biāo)簽解析之前,先寫一個(gè)自定義標(biāo)簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...

    ixlei 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(三)

    摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創(chuàng)建實(shí)例完成必須的裝配和進(jìn)行最終的注冊(cè)來完成元素的解析和注冊(cè),下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創(chuàng)建BeanDefinitionHolder實(shí)例、完成必須的裝配和進(jìn)行最終的注冊(cè)bean來完成bean元素的解析和注冊(cè),下面...

    xbynet 評(píng)論0 收藏0
  • Spring源碼閱讀——ClassPathXmlApplicationContext(三)

    摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創(chuàng)建實(shí)例完成必須的裝配和進(jìn)行最終的注冊(cè)來完成元素的解析和注冊(cè),下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創(chuàng)建BeanDefinitionHolder實(shí)例、完成必須的裝配和進(jìn)行最終的注冊(cè)bean來完成bean元素的解析和注冊(cè),下面...

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

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

0條評(píng)論

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