日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring 加载、解析applicationContext.xml 流程

發布時間:2024/9/30 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring 加载、解析applicationContext.xml 流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概要

Spring 框架使用了BeanFactory 進行加載 xml 和生成 bean 實例。下面我們分析下Spring加載xml文件的過程。
spring 版本是最新的 4.3.9 release 版本

示例

XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("bean.xml")); User user = User.class.cast(xbf.getBean("user")); System.out.println(user);

我們通過XmlBeanFactory分析下xml的加載過程。通常我們開發的時候一般都是使用ClassPathXmlApplicationContext進行加載配置文件的。原理都一樣,只不過ClassPathXmlApplicationContext寬展了好多功能。但加載xml的原理都一樣。

ClassPathResource 封裝了xml文件信息,可以調用getInputStream() 方法獲取文件。

源碼解析

XmlBeanFactory.java


從代碼中發現XmlBeanFactory委托給XmlBeanDefintionReader進行處理

XmlBeanDefintionReader.java


1. 使用EncodeResource封裝資源文件。如果指定編碼則使用指定編碼進行讀取資源文件。
2. 判斷該資源是否已經加載過
3. 構造InputStream實例,然后調用 doLoadBeanDefinitions() 方法

InputSource 類結構
public class InputSource {private String publicId;private String systemId;private InputStream byteStream;private String encoding;private Reader characterStream;.... }

使用SAX解析、驗證xml的時候需要使用到 publicId和systemId

doLoadBeanDefinitions() 方法


1. 使用SAX解析xml獲取Document對象
2. 根據返回的Document 注冊 Bean 信息

doLoadDocument()

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,getValidationModeForResource(resource), isNamespaceAware()); }

getValidationModeForResource(resource)


判斷xml的文檔驗證機制是DTD還是XSD
1.如果指定驗證模式則使用指定的。
2.如果沒有指定則調用 detectValidationMode 自動檢查
讀取xml文件中的是否保護“DOCTYPE”,如果包含則是DTD,否則則是XSD

getEntityResolver() 方法

EntityResovle作用:SAX解析xml的時候首先讀取xml文檔上的聲明,根據聲明找相應的DTD定義。默認尋找規則:首先通過網絡下載相應的DTD,并認證。網絡下載是一個不確定的過程(網速問題、網絡中斷等),就會出現DTD找不到的情況。而EntityResovle提供了一個尋找DTD的自定義方法,一般我們回吧DTD放到項目中某文件夾下,直接讀取本地的DTD交給SAX解析即可。避免了網絡交換過程。

loadDocument() 方法


通過SAX解析xml。構造DocumentBuilderFactory解析xml。

registerBeanDefinitions() 方法

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();int countBefore = getRegistry().getBeanDefinitionCount();documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() - countBefore;}protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass)); }
  • 使用DefaultBeanDefinitionDocumentReader.class 構造BeanDefinitionDocumentReader 。
  • 記錄已經加載的Bean的個數
  • 加載及注冊Bean
  • 返回這次加載的Bean的個數
  • 從當前代碼中可以看出注冊加載Bean委托給 BeanDefinitionDocumentReader .registerBeanDefinitions() 方法處理

    registerBeanDefinitions() 方法

    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;Element root = doc.getDocumentElement();doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) {BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(getReaderContext(), root, parent);if (this.delegate.isDefaultNamespace(root)) {//判斷xml的beans標簽屬性中是否有profile屬性,并驗證跟web.xml中配置的信息是否匹配String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);if (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {return;}}}preProcessXml(root);parseBeanDefinitions(root, this.delegate);postProcessXml(root);this.delegate = parent; }

    profile 用法

    <!-- spring的applicationContext.xml中配置 --> <beans profile="development">...... </beans> <beans profile="produce">...... </beans><!-- web項目的web.xml中配置 --> <context-param><param-name>spring.profiles.default</param-name><param-value>production</param-value> </context-param>

    可以使用profile來進行切換線上配置和開發環境配置,方便開發使用

    parseBeanDefinitions() 方法

    判斷是自定義便簽還是系統默認標簽。
    1.系統默認的標簽調用parseDefaultElement方法解析
    2.用戶自定義標簽使用parseCustomElement方法解析

    parseDefaultElement() 方法

  • 解析 import 標簽
  • 解析 alias 標簽
  • 解析 bean 標簽
  • 解析 beans 標簽
  • parseCustomElement() 方法

    主要解析自定義的標簽內容
    比如:

    <!-- 用戶自定義標簽 --> <bean id="xxx" class="test.XXX"><mybean:user username="zhangsan"/> </bean><!-- 系統默認實現的自定義標簽 --> <tx:annotation-driven />

    本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
    點擊這里快速進入簡書

    GIT地址:http://git.oschina.net/brucekankan/
    點擊這里快速進入GIT

    總結

    以上是生活随笔為你收集整理的Spring 加载、解析applicationContext.xml 流程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。