003-bean xml 解析流程

一.需求

探討Spring 配置文件 bean.xml 中元素是如何被解析的

二.xml構(gòu)成劃分

1.dispatcher-servlet.xml案例

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:util="http://www.springframework.org/schema/util"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <context:component-scan base-package="com.beijing"
    <bean id="student" class="com.beijing.Student">

</beans>

2.dispatcher-servlet.xml構(gòu)成

2.1schema

schema即beans 標(biāo)簽屬性, 大致分為兩部分 xmlns, xsi:schemaLocation

  • xml namespace,xmlns作用有二
    • 定義與下文xsi:schemaLoaction的關(guān)聯(lián)關(guān)系胚宦,整體結(jié)構(gòu):
      xmlns:mvc="key"
      xsi:schemaLocation="key keyLocation"
    • 定義下文標(biāo)簽的使用方式钝诚,整體結(jié)構(gòu):
      xmlns:context="key"
      <context: component-scan="">
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
  • xsi:schemalocation
    • schemaLocation定義了namespace下面可用的屬性试伙,屬性格式等信息
    • namespace的schema可以有不同版本,比如spring-beans-3.1.xsd 掂僵,spring-beans-4.1.xsd
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  

2.2namespace

  • namespace是上文提到的context,即xmlns:context中的context到千,其他同理

2.3element

  • element為<context:component-scan="">中的component-scan
  • 可以做如此類比:namespace為MySQL中的DB,元素為table湿镀,element為table中的field
  • 那namespace可以使用哪些element呢(只需判斷table中定義了哪些field),這就是上面的schemaLocation的作用了禀梳,如下是schemaLocation value =http://www.springframework.org/schema/context/spring-context-4.1.xsd的大致內(nèi)容
    • 可以看到context下可以定義annotation-config,component-scan等元素
    • 可以看成其中component-scan中定義了可以使用的field,如base-package肠骆,及其use為required不可或缺
<xsd:schema xmlns="http://www.springframework.org/schema/context" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" targetNamespace="http://www.springframework.org/schema/context" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="https://www.springframework.org/schema/beans/spring-beans-4.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="https://www.springframework.org/schema/tool/spring-tool-4.1.xsd"/>
    <xsd:annotation>...</xsd:annotation>
    <xsd:complexType name="propertyPlaceholder">...</xsd:complexType>
    <xsd:element name="property-placeholder">...</xsd:element>
    <xsd:element name="property-override">...</xsd:element>
    <xsd:element name="annotation-config">...</xsd:element>
    <xsd:element name="component-scan">
        <xsd:annotation>...</xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>...</xsd:sequence>
            <xsd:attribute name="base-package" type="xsd:string" use="required">...    </xsd:attribute>
            <xsd:attribute name="resource-pattern" type="xsd:string">...</xsd:attribute>
            <xsd:attribute name="use-default-filters" type="xsd:boolean" default="true">...</xsd:attribute>
            <xsd:attribute name="annotation-config" type="xsd:boolean" default="true">...</xsd:attribute>
            <xsd:attribute name="name-generator" type="xsd:string">...</xsd:attribute>
            <xsd:attribute name="scope-resolver" type="xsd:string">...</xsd:attribute>
            <xsd:attribute name="scoped-proxy">...</xsd:attribute>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="load-time-weaver">...</xsd:element>
    <xsd:element name="spring-configured">...</xsd:element>
    <xsd:element name="mbean-export">...</xsd:element>
    <xsd:element name="mbean-server">...</xsd:element>
    <xsd:complexType name="filterType">...</xsd:complexType>
</xsd:schema>
image.png

三.標(biāo)簽的處理

我們知道,注解還是xml的標(biāo)簽塞耕,作用都是起一個(gè)tag的標(biāo)記蚀腿,最終是由其他處理器去發(fā)現(xiàn)這些標(biāo)簽,并根據(jù)標(biāo)簽執(zhí)行不同的邏輯扫外,所以上面這些namespace和element都對應(yīng)著各自的處理器莉钙,且處理器以namespaceHandler:elementHandler層次結(jié)構(gòu)封裝

1.element處理器

  • spring jar 包的/META-INF/目錄下,有spring.handlers文件筛谚,該文件定義了若干element 處理器磁玉,如spring-context-4.2.1.RELEASE.jar包下的/META-INF/spring.handlers文件
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
  • 再看ContextNamespaceHandler類
    • 針對component-scan可以看到new ComponentScanBeanDefinitionParser()
public class ContextNamespaceHandler extends NamespaceHandlerSupport {

    @Override
    public void init() {
        registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
        registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
        registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
        registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
    }

}
  • 查看父類NamespaceHandlerSupport實(shí)現(xiàn)子類
    • 大概有13個(gè)實(shí)現(xiàn)類
    • 且分布在不同的jar包中,比如AopNamespaceHandler子類在spring-aop-4.2.1.RELEASE.jar包中**
    • 如此說明我們可以定義自己namespace處理類驾讲,并保存到/META-INF/spring.handlers中
      image.png
public class AopNamespaceHandler extends NamespaceHandlerSupport {

    /**
     * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
     * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
     * and '{@code scoped-proxy}' tags.
     */
    @Override
    public void init() {
        // In 2.0 XSD as well as in 2.1 XSD.
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

        // Only in 2.0 XSD: moved to context namespace as of 2.1
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }

}  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚊伞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吮铭,更是在濱河造成了極大的恐慌时迫,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谓晌,死亡現(xiàn)場離奇詭異掠拳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纸肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門溺欧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人柏肪,你說我怎么就攤上這事姐刁。” “怎么了烦味?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵龙填,是天一觀的道長。 經(jīng)常有香客問我拐叉,道長岩遗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任凤瘦,我火速辦了婚禮宿礁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔬芥。我一直安慰自己梆靖,他們只是感情好控汉,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著返吻,像睡著了一般姑子。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上测僵,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天街佑,我揣著相機(jī)與錄音,去河邊找鬼捍靠。 笑死沐旨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的榨婆。 我是一名探鬼主播磁携,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼良风!你這毒婦竟也來了谊迄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤烟央,失蹤者是張志新(化名)和其女友劉穎鳞上,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吊档,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篙议,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怠硼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鬼贱。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖香璃,靈堂內(nèi)的尸體忽然破棺而出这难,到底是詐尸還是另有隱情,我是刑警寧澤葡秒,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布姻乓,位于F島的核電站,受9級特大地震影響眯牧,放射性物質(zhì)發(fā)生泄漏蹋岩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一学少、第九天 我趴在偏房一處隱蔽的房頂上張望剪个。 院中可真熱鬧,春花似錦版确、人聲如沸扣囊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侵歇。三九已至骂澄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惕虑,已是汗流浹背坟冲。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枷遂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓棋嘲,卻偏偏與公主長得像酒唉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子沸移,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容