摘要:的繼承關系繼承了,實現了接口。是所有容器的頂級接口,中所有容器都是基于的。方法創建一個新的容器。在本方法中,最重要的是,調用這個方法解析配置文件,注冊。
ClassPathXmlApplicationContext的繼承關系
ClassPathXmlApplicationContext繼承了AbstractXmlApplicationContext,實現了ApplicationContext接口。BeanFactory是所有容器的頂級接口,spring中所有容器都是基于BeanFactory的。ClassPathXmlApplicationContext繼承關系如下圖:
ClassPathXmlApplicationContext中有多個構造方法,最終都通過如下的構造方法初始化容器:
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
其中,refresh()方法完成了容器的初始化。
refresh()方法的實現分析refresh()方法的實現代碼如下
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 上下文刷新的準備工作,完成一下工作: //1、設置啟動時間、是否關閉和是否激活 //2、在上下文中初始化任何占位符屬性資源 //3、驗證標記為必需的屬性文件是可解析的 prepareRefresh(); // 創建DefaultListableBeanFactory實例,解析xml配置文件,注冊bean ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //對BeanFactory進行各種功能填充 //在此方法中,增加的支持@Qualifier與@Autowired這兩個注解 prepareBeanFactory(beanFactory); try { // 由子類實現,可進行自定義擴展 postProcessBeanFactory(beanFactory); // 激活BeanFactory的處理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // 初始化message資源 initMessageSource(); // 為這個context初始化一個事件廣播器 initApplicationEventMulticaster(); // 由子類實現,初始化其他bean onRefresh(); // 注冊已實現ApplicationListener接口的Bean registerListeners(); // 實例化所有非延遲初始化的單例模式bean finishBeanFactoryInitialization(beanFactory); // 完成刷新過程,通知生命周期處理器lifecycleProcessor刷新過程,同時發出ContextRefreshEvent通知監聽者 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()方法的實現
此方法主要作用是創建DefaultListableBeanFactory實例,解析xml配置文件,注冊bean。內部調用了調用了AbstractRefreshableApplicationContext類的refreshBeanFactory()方法創建bean工廠。refreshBeanFactory()方法實現如下:
protected final void refreshBeanFactory() throws BeansException { //如果beanfactory存在,銷毀所以bean和關閉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,關閉beanfactory。createBeanFactory()方法創建一個新的容器。在本方法中,最重要的是loadBeanDefinitions(beanFactory),調用這個方法解析xml配置文件,注冊bean。
loadBeanDefinitions(beanFactory)方法的實現如下protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 根據給定的BeanFactory創建一個新的 XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 根據上下文配置bean definition reader beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); //通過beanDefinitionReader解析xml配置文件,注冊bean loadBeanDefinitions(beanDefinitionReader); }
在XmlBeanDefinitionReader中實現了loadBeanDefinitions(beanDefinitionReader)方法,代碼如下:
//省略了異常處理相關代碼,主要邏輯如下 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { //從encodedResource中得到InputSource和Resource SetcurrentResources = this.resourcesCurrentlyBeingLoaded.get(); InputStream inputStream = encodedResource.getResource().getInputStream(); InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //調用此方法加載BeanDefinition return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); }
doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,從資源文件中讀取Document,并且調用registerBeanDefinitions(doc, resource)注冊BeanDefinition,省略無關代碼,實現如下:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //從resource中讀取得到Document Document doc = doLoadDocument(inputSource, resource); //注冊BeanDefinition return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } }
在registerBeanDefinitions(doc, resource)方法中,BeanDefinition的注冊時委托給BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法進行注冊的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69654.html
摘要:在的方法中,遍歷每一個節點,判斷是否為默認命名空間中的節點,如果是非默認命名空間的,調用方法進行處理。在學習自定義標簽解析之前,先寫一個自定義標簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...
摘要:在的方法中,遍歷每一個節點,判斷是否為默認命名空間中的節點,如果是非默認命名空間的,調用方法進行處理。在學習自定義標簽解析之前,先寫一個自定義標簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...
摘要:在的方法中,遍歷每一個節點,判斷是否為默認命名空間中的節點,如果是非默認命名空間的,調用方法進行處理。在學習自定義標簽解析之前,先寫一個自定義標簽的。 在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)方法中,遍歷每一...
摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創建實例完成必須的裝配和進行最終的注冊來完成元素的解析和注冊,下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創建BeanDefinitionHolder實例、完成必須的裝配和進行最終的注冊bean來完成bean元素的解析和注冊,下面...
摘要:在上一篇源碼閱讀二文章的最后,需要解析元素,創建實例完成必須的裝配和進行最終的注冊來完成元素的解析和注冊,下面分別閱讀三步的源碼。 在上一篇Spring源碼閱讀——ClassPathXmlApplicationContext(二)文章的最后,需要解析bean元素,創建BeanDefinitionHolder實例、完成必須的裝配和進行最終的注冊bean來完成bean元素的解析和注冊,下面...
閱讀 2038·2021-11-19 11:37
閱讀 727·2021-11-11 16:54
閱讀 1176·2021-11-02 14:44
閱讀 3072·2021-09-02 15:40
閱讀 2378·2019-08-30 15:44
閱讀 968·2019-08-29 11:17
閱讀 1069·2019-08-26 14:06
閱讀 1562·2019-08-26 13:47