spring-schema文件解析(-)

由於作者這方面也是新手,故而大神可以直接略過,權當自己留下的筆記,謬誤之處勿噴~
要學習spring schemas及其解析過程,我們應該首先:
1. 熟悉XML/XHTML的基本指示
2. w3school schema課程

3. java及Spring熟練使用

接下來正式開始

首先來看一個spring-beans-4.3.xsd的文件主要內容:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<xsd:schema xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.springframework.org/schema/beans">

    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>

    <xsd:annotation>
        <xsd:documentation><![CDATA[
	Spring XML Beans Schema, version 4.3
	Authors: Juergen Hoeller, Rob Harrop, Mark Fisher, Chris Beams

	This defines a simple and consistent way of creating a namespace
	of JavaBeans objects, managed by a Spring BeanFactory, read by
	XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader).

	This document type is used by most Spring functionality, including
	web application contexts, which are based on bean factories.

	Each "bean" element in this document defines a JavaBean.
	Typically the bean class is specified, along with JavaBean properties
	and/or constructor arguments.

	A bean instance can be a "singleton" (shared instance) or a "prototype"
	(independent instance). Further scopes can be provided by extended
	bean factories, for example in a web environment.

	References among beans are supported, that is, setting a JavaBean property
	or a constructor argument to refer to another bean in the same factory
	(or an ancestor factory).

	As alternative to bean references, "inner bean definitions" can be used.
	Such inner beans do not have an independent lifecycle; they are typically
	anonymous nested objects that share the scope of their containing bean.

	There is also support for lists, sets, maps, and java.util.Properties
	as bean property types or constructor argument types.
		]]></xsd:documentation>
    </xsd:annotation>

    <!-- base types -->
    <!--抽象的基礎符合類型-->
    <xsd:complexType name="identifiedType" abstract="true">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	The unique identifier for a bean. The scope of the identifier
	is the enclosing bean factory.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="id" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The unique identifier for a bean. A bean id may not be used more than once
	within the same <beans> element.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <!-- Top-level <beans> tag -->
    <!-- beans標籤 -->
    <!--doc: beans標籤bean元素和其他元素的容器,也是xml配置文件的根元素,允許所有嵌套bean的默認值。 -->
    <!--beans標籤也可以嵌套於beans標籤體內 ---- 出於定義一個有確定默認值的beans子集或者用於註冊profles並激活profile的目的-->
    <!--注意:此類beans標籤必須被聲明爲spring beans xml config的最後一個元素-->
    <xsd:element name="beans">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Container for <bean> and other elements, typically the root element in the document.
	Allows the definition of default values for all nested bean definitions. May itself
	be nested for the purpose of defining a subset of beans with certain default values or
	to be registered only when certain profile(s) are active. Any such nested <beans> element
	must be declared as the last element in the document.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>
                <!--定義了 description, import, alias, bean, beans標籤,每個標籤都一個出現一次或多次。
                    其中description必須放在第一位,可以出現0此或多次;
                    其他三個標籤可以沒有先後順序,也可以是出現0次或多次
                    beans標籤必須放在末位;

                -->
                <!--
                    定義了一個可選的屬性:profile,類型string
                -->
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element ref="import"/>
                    <xsd:element ref="alias"/>
                    <xsd:element ref="bean"/>
                    <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:choice>
                <xsd:element ref="beans" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:attribute name="profile" use="optional" type="xsd:string">
                <!--profiles的集合是爲了確定將要解析的beans集合,即是此刻哪一個beans標籤體內的元素將要被解析,
                多個profile可以用空格, 逗號, 分號分割-->
                <!--如果在激活文件時,一個或多個profile被激活,則對應的beans標籤體內的元素被解析, 其中所有的bean都會被註冊 -->
                <!--如果解析時,沒有對應的profile被激活,那麼全部的元素和它的內容都將被忽略。-->
                <!--如果一個profile前綴加上了否定符號"!"
                    <beans profile="p1,!p2">
                    表明p1被激活而p2未被激活
                -->
                <!--profiles可通過以下兩種方式被激活:
                程序式配置:
                    ConfigurableEnvironment#setActiveProfiles(String...)
			        ConfigurableEnvironment#setDefaultProfiles(String...)
			    屬性配置式(可通過啓動時的 -D 系統屬性, 環境變量或者servlet context init params):
			        spring.profiles.active=p1,p2
			        spring.profiles.default=p1,p2
                -->
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The set of profiles for which this <beans> element should be parsed. Multiple profiles
	can be separated by spaces, commas, or semi-colons.

	If one or more of the specified profiles are active at time of parsing, the <beans>
	element will be parsed, and all of its <bean> elements registered, <import>
	elements followed, etc.  If none of the specified profiles are active at time of
	parsing, then the entire element and its contents will be ignored.

	If a profile is prefixed with the NOT operator '!', e.g.

		<beans profile="p1,!p2">

	indicates that the <beans> element should be parsed if profile "p1" is active or
	if profile "p2" is not active.

	Profiles are activated in one of two ways:
		Programmatic:
			ConfigurableEnvironment#setActiveProfiles(String...)
			ConfigurableEnvironment#setDefaultProfiles(String...)

		Properties (typically through -D system properties, environment variables, or
		servlet context init params):
			spring.profiles.active=p1,p2
			spring.profiles.default=p1,p2
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--定義默認屬性:默認延遲加載:default-lazy-init:-->
            <!--doc: 默認的延遲加載值,請看bean標籤的lazy-init屬性, 默認值是default,表示從嵌套的外部beans中繼承,否則返回false -->
            <xsd:attribute name="default-lazy-init" default="default" type="defaultable-boolean">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The default 'lazy-init' value; see the documentation for the
	'lazy-init' attribute of the 'bean' element. The default is "default",
	indicating inheritance from outer 'beans' sections in case of nesting,
	otherwise falling back to "false".
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--默認的“合併”值; 請參閱各種集合元素的“合併”屬性文檔。 缺省值爲“default”,表示嵌套時從外部“bean”部分繼承,否則返回“false”。-->
            <xsd:attribute name="default-merge" default="default" type="defaultable-boolean">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The default 'merge' value; see the documentation for the 'merge'
	attribute of the various collection elements. The default is "default",
	indicating inheritance from outer 'beans' sections in case of nesting,
	otherwise falling back to "false".
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--默認的autowire值, 請參閱bean元素的autowire屬性文檔, 默認值是default, 表明嵌套時從外部beans繼承, 否則返回false-->
            <!--無外部驅動的自動裝配-->
            <!--定義了autowire的自動裝配的可選枚舉值: default, no, byname, byType, constructor-->
            <xsd:attribute name="default-autowire" default="default">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The default 'autowire' value; see the documentation for the
	'autowire' attribute of the 'bean' element. The default is "default",
	indicating inheritance from outer 'beans' sections in case of nesting,
	otherwise falling back to "no" (i.e. no externally driven autowiring).
					]]></xsd:documentation>
                </xsd:annotation>
                <xsd:simpleType>
                    <xsd:restriction base="xsd:NMTOKEN">
                        <xsd:enumeration value="default"/>
                        <xsd:enumeration value="no"/>
                        <xsd:enumeration value="byName"/>
                        <xsd:enumeration value="byType"/>
                        <xsd:enumeration value="constructor"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:attribute>
            <!--這個部分沒有太看懂,看個大概 -->
            <!--默認裝配候選值:
                用於標識autowire的候選值的默認bean名稱匹配模式, 如*Service, *Dao, 或者 “*Service, *Dao”
                詳細請參閱bean的autowire-candidate屬性的更多細節
            -->
            <xsd:attribute name="default-autowire-candidates" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	A default bean name pattern for identifying autowire candidates:
	e.g. "*Service", "data*", "*Service*", "data*Service".
	Also accepts a comma-separated list of patterns: e.g. "*Service,*Dao".
	See the documentation for the 'autowire-candidate' attribute of the
	'bean' element for the semantic details of autowire candidate beans.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--默認初始化方法: 參看bena的init-method屬性-->
            <xsd:attribute name="default-init-method" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The default 'init-method' value; see the documentation for the
	'init-method' attribute of the 'bean' element.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--默認銷燬方法: 請看bean元素的destroy-method屬性-->
            <xsd:attribute name="default-destroy-method" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The default 'destroy-method' value; see the documentation for the
	'destroy-method' attribute of the 'bean' element.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <xsd:anyAttribute namespace="##other" processContents="lax"/>
        </xsd:complexType>
    </xsd:element>

    <!--beans元素默認引用的第一個元素,必須出現在beans元素的首個元素,可出現0次或多次 -->
    <!--包含描述封閉元素用途的信息文本。主要用於XML bean定義文檔的用戶參考手冊。-->
    <xsd:element name="description">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Contains informative text describing the purpose of the enclosing element.
	Used primarily for user documentation of XML bean definition documents.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
        </xsd:complexType>
    </xsd:element>

    <!--import元素:聲明要導入的xml bean定義源文件-->
    <!--屬性:
        resource:必須指定。用於指定xml源文件的相對路徑
    -->
    <xsd:element name="import">
        <xsd:annotation>
            <xsd:documentation source="java:org.springframework.core.io.Resource"><![CDATA[
	Specifies an XML bean definition resource to import.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="resource" type="xsd:string" use="required">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The relative resource location of the XML (bean definition) file to import,
	for example "myImport.xml" or "includes/myImport.xml" or "../myImport.xml".
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--alias元素:爲一個bean定義別名(該bean可以聲明在不同的源文件中)-->
    <!--屬性:
        name: 需要被定義別名的bean, 必須
        alias: bean的別名,必須
    -->
    <xsd:element name="alias">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Defines an alias for a bean (which can reside in a different definition
	resource).
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="name" type="xsd:string" use="required">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the bean to define an alias for.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="alias" type="xsd:string" use="required">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The alias name to define for the bean.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--bean元素公用組元素-->
    <xsd:group name="beanElements">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="meta"/>
                <xsd:element ref="constructor-arg"/>
                <xsd:element ref="property"/>
                <xsd:element ref="qualifier"/>
                <xsd:element ref="lookup-method"/>
                <xsd:element ref="replaced-method"/>
                <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>
    <!--bean屬性組元素
        name:可以用來創建一個或多個非法ID用來標識一個bean, 多個別名可以用一個或多個逗號, 空格,分號或他們的組合來分隔
        class: bean的全類名,除非它是作爲一個父bean爲子bean服務
        parent:父bean定義。如果未聲明全類名,則會使用父類的class,但是也可以重寫。
                在重寫的額情況下,子類必須與父類兼容,如接受父類的屬性和構造器參數(如果有的話)
                子bean定義將會繼承構造器參數,屬性值和重寫的父類方法並且可選添加新值。
                如果聲明初始化方法,銷燬方法和工廠bean,工廠方法,則將重寫父類的相關設置。
        scope:bean的scope。默認singleton。任何通過給定id調用該bean的方法都會獲得一個該bean的共享單實例。
                或者prototype:每次調用都會產生新的實例。
                默認情況下是singleton。除非它繼承了父類的scope
                singleton是最常用的,並且是多線程情況下的最理想選擇。其他選項如request和session,通常由擴展bena工廠支持。
                如web環境下
                內部bean將繼承包含他們的bean的scope。如果包含他們的bean是一個singleton,則內部bean是singleton;
                如果包含他們的bean是一個prototype,則內部bean也是一個prototype
        abstract:抽象bean,用來告訴容器不要實例化該bean,而指示作爲一個父bean用來創建子類bean。
                  默認情況下是false,指定true用來告訴容器任何情況下都不要嘗試來實例化該bean
                  該屬性不會被繼承,每一個bean都需要單獨指定該屬性
        lazy-init:表明該bean釋放應該被延遲初始化,如果false,它將會被容器工廠啓動時進行單實例初始化。 默認值false
                  注意:該屬性將不會被子bean繼承。因此,每創建一個bean定義都需要單獨指定該屬性。它可能從beans屬性中default-lazy-init屬性
                  繼承和共享。或者可能從嵌套的外部bean繼承(如不同的profile)
        autowire:控制bean的屬性是否自動裝配:
                  這是一個不要再配置文件的bean定義中顯式編碼的無意識的自動過程。spring容器會自動解決依賴。有效默認值爲no。
                    共有4種模式:
                    no:傳統的spring默認模式。無自動裝配。bean引用必須在xml文件使用ref元素或ref屬性顯示聲明。
                        我們仍建議這樣引用因爲這會使文檔更加明確。
                        注意:這個默認模式允許註解驅動的自動裝配。如果被激活,no僅指外部驅動的自動裝配,而不會影響bean本身的自動裝配需求
                    byname:通過屬性名稱自動裝配。如果一個Cat類暴露出dog屬性。spring將會嘗試把當前容器中名稱爲dog的bean裝配上去。
                            如果沒有匹配的名稱,則什麼也不會發生。
                    bytype:如果容器中有一個bean的類型與該屬性的類型相同,則會自動裝配。如果有超過一個,則會引發致命錯誤。
                            你將不能通過bytype進行自動裝配。如果沒有,也不會發生異常。
                    constructor:通過構造函數類似於bytype裝配,如果bean工廠沒有符合構造參數類型的bean,則會發生致命異常
                    注意:這個屬性不會繼承,每個bean都需要單獨指定。可能通過外部的beans中的default-autowire繼承。或者通過
                          外部嵌套的bean繼承。
        depends-on: 該bean初始化所依賴的beans。bean工廠將會確保在該bean初始化之前去初始化這些beans
                    注意:這些依賴關係通常通過bean屬性或者構造參數進行表示。這個屬性應該其他類型依賴的必須,如靜態或數據庫啓動準備(沒太看懂)
                    注意:該屬性不能被繼承,每一個元素都應該單獨指定
        autowire-candidate:當裝配其他bean時,容器尋找匹配的bean時,該bean是否被認爲是匹配的候選人。
                            注意:這不會影響name的顯示引用。因爲即使未被指定未繼承人,該bean依然會被解析。
        primary:指定該bean應該被優先裝配當有多個候選人滿足裝配一個單值依賴。如果在候選人中存在一個primary bean,它將會被優先裝配。
        inti-method:在設置屬性後要執行的自定義初始化方法的名稱。該方法不能有參數,但是可以拋異常。
                         這是一個實現initializingBean接口或者@Postconstructor註解的替代方法
        destroy-method:在bean容器關閉時的自定義銷燬方法。該方法不能有參數,但是可以拋異常。
                        這是實現DisposableBean接口的以及java Closeable/Autocloseable接口以及@Predestroy註解的替代方法
                        注意:只有該bean的生命週期被容器全權控制的bean纔可以執行該方法--通常情況下是單實例bean,其他scopebean不適用。
        factory-method: 創建此對象的工廠方法的名稱。如果需要參數,需要通過constructor-arg參數來指定工廠的參數。自動裝配不適用於工廠方法
                        如果同時存在class屬性,工廠方法將是靜態的,通常這將會與被構造對象的類相同--例如,工廠方法被用作替代構造函數。
                        但是,它可能是不同的類。在這個情況下,創建的對象將不是class屬性指定的類,這與工廠bean行爲類似。
                        如果存在factory-bean屬性且class屬性沒有被使用, 通過給定的bean名稱調用getBean()獲得返回的object方法將會是一個實例方法。
                        該factorybean可以被定義爲singleton或者prototype
                        工廠方法可以有任意數量的參數u,不支持自動裝配。結合構造函數索引使用工廠方法進行構造注入。
                        setter注入可以結合工廠方法使用。方法注入不能,因爲工廠方法返回一個容器創建的將會被使用的bean實例。

        factory-bean: 使用工廠方法時class屬性的替代品。
                           如果聲明該屬性,則不能使用class屬性。
                           該屬性必須被設置爲當前工廠或父工廠中包含的相關工廠方法的bean名稱。這允許工廠進行自動依賴配置,
                           並使用實例方法(而不是靜態方法)
    -->
    <xsd:attributeGroup name="beanAttributes">
        <xsd:attribute name="name" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Can be used to create one or more aliases illegal in an (XML) id.
	Multiple aliases can be separated by any number of spaces, commas,
	or semi-colons (or indeed any mixture of the three).
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="class" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation source="java:java.lang.Class"><![CDATA[
	The fully qualified name of the bean's class, except if it serves only
	as a parent definition for child bean definitions.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="parent" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The name of the parent bean definition.

	Will use the bean class of the parent if none is specified, but can
	also override it. In the latter case, the child bean class must be
	compatible with the parent, i.e. accept the parent's property values
	and constructor argument values, if any.

	A child bean definition will inherit constructor argument values,
	property values and method overrides from the parent, with the option
	to add new values. If init method, destroy method, factory bean and/or
	factory method are specified, they will override the corresponding
	parent settings.

	The remaining settings will always be taken from the child definition:
	depends on, autowire mode, scope, lazy init.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="scope" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The scope of this bean: typically "singleton" (one shared instance,
	which will be returned by all calls to getBean with the given id), or
	"prototype" (independent instance resulting from each call to getBean).

	By default, a bean will be a singleton, unless the bean has a parent
	bean definition in which case it will inherit the parent's scope.

	Singletons are most commonly used, and are ideal for multi-threaded
	service objects. Further scopes, such as "request" or "session", might
	be supported by extended bean factories (e.g. in a web environment).

	Inner bean definitions inherit the scope of their containing bean
	definition, unless explicitly specified: The inner bean will be a
	singleton if the containing bean is a singleton, and a prototype if
	the containing bean is a prototype, etc.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="abstract" type="xsd:boolean">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Is this bean "abstract", that is, not meant to be instantiated itself
	but rather just serving as parent for concrete child bean definitions?
	The default is "false". Specify "true" to tell the bean factory to not
	try to instantiate that particular bean in any case.

	Note: This attribute will not be inherited by child bean definitions.
	Hence, it needs to be specified per abstract bean definition.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <!--
        -->
        <xsd:attribute name="lazy-init" default="default" type="defaultable-boolean">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Indicates whether this bean is to be lazily initialized. If "false",
	it will be instantiated on startup by bean factories that perform eager
	initialization of singletons. The effective default is "false".

	Note: This attribute will not be inherited by child bean definitions.
	Hence, it needs to be specified per concrete bean definition. It can be
	shared through the 'default-lazy-init' attribute at the 'beans' level
	and potentially inherited from outer 'beans' defaults in case of nested
	'beans' sections (e.g. with different profiles).
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="autowire" default="default">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Controls whether bean properties are "autowired".
	This is an automagical process in which bean references don't need
	to be coded explicitly in the XML bean definition file, but rather the
	Spring container works out dependencies. The effective default is "no".

	There are 4 modes:

	1. "no"
	The traditional Spring default. No automagical wiring. Bean references
	must be defined in the XML file via the <ref/> element (or "ref"
	attribute). We recommend this in most cases as it makes documentation
	more explicit.

	Note that this default mode also allows for annotation-driven autowiring,
	if activated. "no" refers to externally driven autowiring only, not
	affecting any autowiring demands that the bean class itself expresses.

	2. "byName"
	Autowiring by property name. If a bean of class Cat exposes a "dog"
	property, Spring will try to set this to the value of the bean "dog"
	in the current container. If there is no matching bean by name, nothing
	special happens.

	3. "byType"
	Autowiring if there is exactly one bean of the property type in the
	container. If there is more than one, a fatal error is raised, and
	you cannot use byType autowiring for that bean. If there is none,
	nothing special happens.

	4. "constructor"
	Analogous to "byType" for constructor arguments. If there is not exactly
	one bean of the constructor argument type in the bean factory, a fatal
	error is raised.

	Note that explicit dependencies, i.e. "property" and "constructor-arg"
	elements, always override autowiring.

	Note: This attribute will not be inherited by child bean definitions.
	Hence, it needs to be specified per concrete bean definition. It can be
	shared through the 'default-autowire' attribute at the 'beans' level
	and potentially inherited from outer 'beans' defaults in case of nested
	'beans' sections (e.g. with different profiles).
				]]></xsd:documentation>
            </xsd:annotation>
            <xsd:simpleType>
                <xsd:restriction base="xsd:NMTOKEN">
                    <xsd:enumeration value="default"/>
                    <xsd:enumeration value="no"/>
                    <xsd:enumeration value="byName"/>
                    <xsd:enumeration value="byType"/>
                    <xsd:enumeration value="constructor"/>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:attribute>
        <!--
        -->
        <xsd:attribute name="depends-on" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The names of the beans that this bean depends on being initialized.
	The bean factory will guarantee that these beans get initialized
	before this bean.

	Note that dependencies are normally expressed through bean properties
	or constructor arguments. This property should just be necessary for
	other kinds of dependencies like statics (*ugh*) or database preparation
	on startup.

	Note: This attribute will not be inherited by child bean definitions.
	Hence, it needs to be specified per concrete bean definition.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="autowire-candidate" default="default" type="defaultable-boolean">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Indicates whether or not this bean should be considered when looking
	for matching candidates to satisfy another bean's autowiring requirements.
	Note that this does not affect explicit references by name, which will get
	resolved even if the specified bean is not marked as an autowire candidate.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="primary" type="xsd:boolean">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Specifies that this bean should be given preference when multiple
	candidates are qualified to autowire a single-valued dependency.
	If exactly one 'primary' bean exists among the candidates, it
	will be the autowired value.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="init-method" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The name of the custom initialization method to invoke after setting
	bean properties. The method must have no arguments, but may throw any
	exception.

	This is an alternative to implementing Spring's InitializingBean
	interface or marking a method with the PostConstruct annotation.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="destroy-method" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The name of the custom destroy method to invoke on bean factory shutdown.
	The method must have no arguments, but may throw any exception.

	This is an alternative to implementing Spring's DisposableBean
	interface or the standard Java Closeable/AutoCloseable interface,
	or marking a method with the PreDestroy annotation.

	Note: Only invoked on beans whose lifecycle is under the full
	control of the factory - which is always the case for singletons,
	but not guaranteed for any other scope.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="factory-method" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The name of a factory method to use to create this object. Use
	constructor-arg elements to specify arguments to the factory method,
	if it takes arguments. Autowiring does not apply to factory methods.

	If the "class" attribute is present, the factory method will be a static
	method on the class specified by the "class" attribute on this bean
	definition. Often this will be the same class as that of the constructed
	object - for example, when the factory method is used as an alternative
	to a constructor. However, it may be on a different class. In that case,
	the created object will *not* be of the class specified in the "class"
	attribute. This is analogous to FactoryBean behavior.

	If the "factory-bean" attribute is present, the "class" attribute is not
	used, and the factory method will be an instance method on the object
	returned from a getBean call with the specified bean name. The factory
	bean may be defined as a singleton or a prototype.

	The factory method can have any number of arguments. Autowiring is not
	supported. Use indexed constructor-arg elements in conjunction with the
	factory-method attribute.

	Setter Injection can be used in conjunction with a factory method.
	Method Injection cannot, as the factory method returns an instance,
	which will be used when the container creates the bean.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="factory-bean" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Alternative to class attribute for factory-method usage.
	If this is specified, no class attribute should be used.
	This must be set to the name of a bean in the current or
	ancestor factories that contains the relevant factory method.
	This allows the factory itself to be configured using Dependency
	Injection, and an instance (rather than static) method to be used.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:anyAttribute namespace="##other" processContents="lax"/>
    </xsd:attributeGroup>

    <xsd:element name="meta" type="metaType">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Arbitrary metadata attached to a bean definition.
			]]></xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <!--metaType:
        元數據類型:bean中可定義元數據的key,value對,兩個屬性必須
    -->
    <xsd:complexType name="metaType">
        <xsd:attribute name="key" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The key name of the metadata attribute being defined.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="value" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The value of the metadata attribute being defined (as a simple String).
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <!--bean定義:
        使用上面定義的兩個複合類型:
            beanElements
            beanAttributes
    -->
    <xsd:element name="bean">
        <xsd:annotation>
            <xsd:documentation source="java:org.springframework.beans.factory.config.BeanDefinition"><![CDATA[
	Defines a single (usually named) bean.

	A bean definition may contain nested tags for constructor arguments,
	property values, lookup methods, and replaced methods. Mixing constructor
	injection and setter injection on the same bean is explicitly supported.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="identifiedType">
                    <xsd:group ref="beanElements"/>
                    <xsd:attributeGroup ref="beanAttributes"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--constructor-arg:
        bean definitions可以聲明0個或多個構造參數,這將會替代默認的自動裝配constructor。
        構造函數參數通過構造參數列表索引或者通過參數類型進行關聯;
        注意:一個泛型參數值智慧被使用一次,而不是可能匹配多次
        構造函數元素也可以在靜態或實例工廠方法進行結合注入時使用
        定義了多個元素類型引用:如bean ref idref value null array list set map props等,
        可以聲明一次或多次
    -->
    <xsd:element name="constructor-arg">
        <xsd:annotation>
            <xsd:documentation source="java:org.springframework.beans.factory.config.ConstructorArgumentValues">
                <![CDATA[
	Bean definitions can specify zero or more constructor arguments.
	This is an alternative to "autowire constructor".
	Arguments correspond to either a specific index of the constructor
	argument list or are supposed to be matched generically by type.

	Note: A single generic argument value will just be used once, rather
	than potentially matched multiple times (as of Spring 1.1).

	constructor-arg elements are also used in with the
	factory-method element to construct beans using static or instance
	factory methods.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="description" minOccurs="0"/>
                <xsd:choice minOccurs="0" maxOccurs="1">
                    <xsd:element ref="bean"/>
                    <xsd:element ref="ref"/>
                    <xsd:element ref="idref"/>
                    <xsd:element ref="value"/>
                    <xsd:element ref="null"/>
                    <xsd:element ref="array"/>
                    <xsd:element ref="list"/>
                    <xsd:element ref="set"/>
                    <xsd:element ref="map"/>
                    <xsd:element ref="props"/>
                    <xsd:any namespace="##other" processContents="strict"/>
                </xsd:choice>
            </xsd:sequence>
            <!--index:構造函數參數裏的確切索引位置。是爲了避免兩個函數參數類型相同的而出現混淆的情況-->
            <xsd:attribute name="index" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The exact index of the argument in the constructor argument list.
	Only needed to avoid ambiguities, e.g. in case of 2 arguments of
	the exact same type.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--type:確切的構造函數參數類型。只是爲了避免混淆。例如,兩個單參數構造函數都可能從String轉換而來-->
            <xsd:attribute name="type" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The exact type of the constructor argument. Only needed to avoid
	ambiguities, e.g. in case of 2 single argument constructors
	that can both be converted from a String.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--name: 構造函數參數表中參數的確定名稱,僅爲了避免混淆。-->
            <xsd:attribute name="name" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The exact name of the argument in the constructor argument list.
	Only needed to avoid ambiguities, e.g. in case of 2 arguments of
	the exact same type. Note: This requires debug symbols to be
	stored in the class file in order to introspect argument names!
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--ref: <ref bean='...'/>的縮寫-->
            <xsd:attribute name="ref" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<ref bean='...'/>" element.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <!--value:<value>...<value/>的縮寫-->
            <xsd:attribute name="value" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<value>...<value/>" element.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>

    <!--property:
        一個bean definitions可以有0個或多個屬性。Properties元素與bean暴露出來的setter方法關聯。
        spring指示基元,引用同一個或相關工廠,lists,map和properties中的bean
    -->
    <xsd:element name="property" type="propertyType">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Bean definitions can have zero or more properties.
	Property elements correspond to JavaBean setter methods exposed
	by the bean classes. Spring supports primitives, references to other
	beans in the same or related factories, lists, maps and properties.
			]]></xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <!--qualifier:
            Bean定義可以提供限定符以匹配字段或參數上的註釋以實現細粒度的自動導向候選解析。
            type: 默認爲Qualifier
            value:非必要
    -->
    <xsd:element name="qualifier">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Bean definitions can provide qualifiers to match against annotations
	on a field or parameter for fine-grained autowire candidate resolution.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:attribute name="type" type="xsd:string" default="org.springframework.beans.factory.annotation.Qualifier"/>
            <xsd:attribute name="value" type="xsd:string"/>
        </xsd:complexType>
    </xsd:element>

    <!--
        限定符元素可能包含屬性子元素作爲鍵值對。 這些將可用於匹配autowired字段或參數(如果存在)上限定符註釋的屬性。
    -->
    <xsd:element name="attribute" type="metaType">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A qualifier element may contain attribute child elements as key-value
	pairs. These will be available for matching against attributes of a
	qualifier annotation on an autowired field or parameter if present.
			]]></xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <!--lookup-method:
            lookup-method會使IOC容器重寫給定的方法並返回bean屬性中指定name的bean。這是方法注入的一種方式、
            它是替代實現BeanFactoryAware接口,在運行時調用getBean()返回非單實例bean的一種非常有效的方式
            因此,方法注入是一種實現代碼較小侵入性的選擇。
      name:該方法可能有參數傳遞給目標構造函數或工廠方法。 請注意,出於向後兼容的原因,在給定名稱的非抽象方法
            重載的情況下,只有方法的無參數變體纔會變成容器驅動的查找方法。考慮使用@Lookup註釋以獲得更具體的界限。
      bean: lookup-method將會解析成的當前容器或父容器中的bean。通常情況下該bean是prototype,此時每次lookup-method
            調用都返回一個該bean的一個實例。如果未指定,lookup-method方法的返回值將會以類型爲基準。
    -->
    <xsd:element name="lookup-method">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A lookup method causes the IoC container to override the given method
	and return the bean with the name given in the bean attribute. This is
	a form of Method Injection. It is particularly useful as an alternative
	to implementing the BeanFactoryAware interface, in order to be able to
	make getBean() calls for non-singleton instances at runtime. In this
	case, Method Injection is a less invasive alternative.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="name" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the lookup method. This method may have arguments which
	will be passed on to the target constructor or factory method. Note
	that for backwards compatibility reasons, in a scenario with overloaded
	non-abstract methods of the given name, only the no-arg variant of a
	method will be turned into a container-driven lookup method.
	Consider using the @Lookup annotation for more specific demarcation.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="bean" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the bean in the current or ancestor factories that
	the lookup method should resolve to. Usually this bean will be a
	prototype, in which case the lookup method will return a distinct
	instance on every invocation. If not specified, the lookup method's
	return type will be used for a type-based lookup.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--replaced-method:
            類似於lookup-method機制。replaced-nethod元素被 用來控制IOC容器重寫:方法注入。該機制允許任意代碼覆蓋方法。
        屬性:
            name:將會被IOC容器替代的方法實現的名稱。如果該方法沒有被重載,就沒有使用arg-type 子元素。
                  如果被重載了,所有被重寫的方法都必須使用arg-type子元素。
            replacer: 當前或祖先工廠中MethodReplacer接口實現的Bean名稱。 這可能是一個singleton或prototype bean。
                      如果是原型,則每個方法替換都會使用一個新實例。 通常使用單實例。
    -->
    <xsd:element name="replaced-method">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Similar to the lookup method mechanism, the replaced-method element
	is used to control IoC container method overriding: Method Injection.
	This mechanism allows the overriding of a method with arbitrary code.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element ref="arg-type"/>
                </xsd:choice>
            </xsd:sequence>
            <xsd:attribute name="name" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The name of the method whose implementation must be replaced by the
	IoC container. If this method is not overloaded, there is no need
	to use arg-type subelements. If this method is overloaded, arg-type
	subelements must be used for all override definitions for the method.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <xsd:attribute name="replacer" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation source="java:org.springframework.beans.factory.support.MethodReplacer"><![CDATA[
	Bean name of an implementation of the MethodReplacer interface in the
	current or ancestor factories. This may be a singleton or prototype
	bean. If it is a prototype, a new instance will be used for each
	method replacement. Singleton usage is the norm.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>


    <!--replaced-method中指定重載方法的參數類型
        match: 指定重載方法的參數,如String,爲了方便,通常指定全類名的子字符串,
        因爲參數數量將會被建成,所以這種簡寫通常可以用來保存類型。
    -->
    <xsd:element name="arg-type">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Identifies an argument for a replaced method in the event of
	method overloading.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="match" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	Specification of the type of an overloaded method argument as a String.
	For convenience, this may be a substring of the FQN. E.g. all the
	following would match "java.lang.String":
	- java.lang.String
	- String
	- Str

	As the number of arguments will be checked also, this convenience
	can often be used to save typing.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>

    <!--ref:
            定義一個該工廠或外部工廠(父工廠或內部工廠)中的bean引用
            name:被引用bean的名稱
            praent:被引用bean所在的父容器
    -->
    <xsd:element name="ref">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Defines a reference to another bean in this factory or an external
	factory (parent or included factory).
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="bean" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the referenced bean.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="parent" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the referenced bean in a parent factory.
						]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--idref:被引用bean的id,該bean可以是本工廠或是外部工廠(父工廠或包含的工廠)
        雖然常規的value元素可以起到相同的效果,但是idref會指示spring容器去檢查value月bean的id是否關聯。
    -->
    <xsd:element name="idref">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	The id of another bean in this factory or an external factory
	(parent or included factory).
	While a regular 'value' element could instead be used for the
	same effect, using idref indicates that the Spring container
	should check that the value actually corresponds to a bean id.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:attribute name="bean" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	The name of the referenced bean.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--value: 一個代表屬性值的String字符串。
               這個屬性可以是string,也可以被轉換成爲需要的類型通過使用JAVABEANS PROPRETYEDITOR 機制。
               這使應用程序開發人員可以編寫自定義的ProperyEditor實現從而可以將string轉換成任何目標對象。
        注意:這僅適用於簡單對象。 通過引用其他bean來填充JavaBean屬性來配置更復雜的對象。
            type: 該value將會被轉換成的具體的類型。僅在目標屬性的類型或者構造函數太過通用的情況下才需要,如集合元素。
    -->
    <xsd:element name="value">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Contains a string representation of a property value.
	The property may be a string, or may be converted to the required
	type using the JavaBeans PropertyEditor machinery. This makes it
	possible for application developers to write custom PropertyEditor
	implementations that can convert strings to arbitrary target objects.

	Note that this is recommended for simple objects only. Configure
	more complex objects by populating JavaBean properties with
	references to other beans.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="type" type="xsd:string">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The exact type that the value should be converted to. Only needed
	if the type of the target property or constructor argument is
	too generic: for example, in case of a collection element.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>

    <!--null:
            表示Java空值。 必要的,因爲一個空的“value”標籤將解析爲一個空的字符串,除非特殊的PropertyEditor這樣做,否則不會解析爲空值。
    -->
    <xsd:element name="null">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Denotes a Java null value. Necessary because an empty "value" tag
	will resolve to an empty String, which will not be resolved to a
	null value unless a special PropertyEditor does so.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
        </xsd:complexType>
    </xsd:element>

    <!-- Collection Elements 集合元素-->
    <xsd:group name="collectionElements">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="bean"/>
                <xsd:element ref="ref"/>
                <xsd:element ref="idref"/>
                <xsd:element ref="value"/>
                <xsd:element ref="null"/>
                <xsd:element ref="array"/>
                <xsd:element ref="list"/>
                <xsd:element ref="set"/>
                <xsd:element ref="map"/>
                <xsd:element ref="props"/>
                <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>

    <!--array數組:
        array可以包含多個內部bean, ref, collection, 或者value元素。
        該配置元素總是會產生一個數組,即使被定義爲值類型映射的值。
    -->
    <xsd:element name="array">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	An array can contain multiple inner bean, ref, collection, or value elements.
	This configuration element will always result in an array, even when being
	defined e.g. as a value for a map with value type Object.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	Enables/disables merging for collections when using parent/child beans.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--list:
            list可以包含多個內部bean或值元素;
            list也可以映射一個數組類型。但需要進行必要的類型轉換。
        merge:使用父/子bean時啓用/禁用合併集合。
    -->
    <xsd:element name="list">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A list can contain multiple inner bean, ref, collection, or value elements.
	A list can also map to an array type; the necessary conversion is performed
	automatically.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	Enables/disables merging for collections when using parent/child beans.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--set:set集合可以包含多個內部bean, ref引用,集合,或值元素-->
    <xsd:element name="set">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A set can contain multiple inner bean, ref, collection, or value elements.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="listOrSetType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	Enables/disables merging for collections when using parent/child beans.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>


    <!--map:從一個key到特定對象的映射。映射可以是空的 。-->
    <xsd:element name="map">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A mapping from a key to an object. Maps may be empty.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="mapType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	Enables/disables merging for collections when using parent/child beans.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--entry:一個map entry可以是內部bena, ref引用,value, 或集合。
               key屬性或子元素提供key
    -->
    <xsd:element name="entry" type="entryType">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A map entry can be an inner bean, ref, value, or collection.
	The key of the entry is given by the "key" attribute or child element.
			]]></xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <!--props與map的不同是,props的值一定是strings, props可以是空-->
    <xsd:element name="props">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	Props elements differ from map elements in that values must be strings.
	Props may be empty.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="propsType">
                    <xsd:attribute name="merge" default="default" type="defaultable-boolean">
                        <xsd:annotation>
                            <xsd:documentation><![CDATA[
	Enables/disables merging for collections when using parent/child beans.
							]]></xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <!--key元素可以包含內部bean, ref, value, collection-->
    <xsd:element name="key">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	A key element can contain an inner bean, ref, value, or collection.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:group ref="collectionElements"/>
        </xsd:complexType>
    </xsd:element>

    <!--屬性的字符串值。注意空格將會被刪除,以避免特定xml格式化所不需要的空格 -->
    <xsd:element name="prop">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
	The string value of the property. Note that whitespace is trimmed
	off to avoid unwanted whitespace caused by typical XML formatting.
			]]></xsd:documentation>
        </xsd:annotation>
        <xsd:complexType mixed="true">
            <xsd:choice minOccurs="0" maxOccurs="unbounded"/>
            <xsd:attribute name="key" type="xsd:string" use="required">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
	The key of the property entry.
					]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
    </xsd:element>

    <!--propertyType:
            name: property的名稱,遵循javabean命名約定
            ref:<ref bean="" 的簡寫
            value: <value><?value>的縮寫

    -->
    <xsd:complexType name="propertyType">
        <xsd:sequence>
            <xsd:element ref="description" minOccurs="0"/>
            <xsd:choice minOccurs="0" maxOccurs="1">
                <xsd:element ref="meta"/>
                <xsd:element ref="bean"/>
                <xsd:element ref="ref"/>
                <xsd:element ref="idref"/>
                <xsd:element ref="value"/>
                <xsd:element ref="null"/>
                <xsd:element ref="array"/>
                <xsd:element ref="list"/>
                <xsd:element ref="set"/>
                <xsd:element ref="map"/>
                <xsd:element ref="props"/>
                <xsd:any namespace="##other" processContents="strict"/>
            </xsd:choice>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	The name of the property, following JavaBean naming conventions.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="ref" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<ref bean='...'/>".
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="value" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<value>...</value>" element.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <!-- Collection Types -->

    <!--collectionType:
        value-type:默認的嵌套值的java類型,必須是全類名
    -->
    <!-- base type for collections that have (possibly) typed nested values -->
    <xsd:complexType name="collectionType">
        <xsd:attribute name="value-type" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation source="java:java.lang.Class"><![CDATA[
	The default Java type for nested values. Must be a fully qualified
	class name.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <!-- 'list' and 'set' collection type -->
    <xsd:complexType name="listOrSetType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:group ref="collectionElements"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 'map' element type -->
    <!--map類:
        key-type:默認的嵌套key的java類型。必須是全類名。
    -->
    <xsd:complexType name="mapType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:sequence>
                    <xsd:element ref="description" minOccurs="0"/>
                    <xsd:choice minOccurs="0" maxOccurs="unbounded">
                        <xsd:element ref="entry"/>
                    </xsd:choice>
                </xsd:sequence>
                <xsd:attribute name="key-type" type="xsd:string">
                    <xsd:annotation>
                        <xsd:documentation source="java:java.lang.Class"><![CDATA[
	The default Java type for nested entry keys. Must be a fully qualified
	class name.
						]]></xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 'entry' element type -->
    <!--entry:
        key;每個map元素都必須在其屬性或子元素中聲明key。key屬性常常時string
        key-ref:<ref bean=""/>的簡寫
        value:<value>...</value>的簡寫
        value-ref:<ref bean='...'/>的簡寫
        value-type: 簡寫替代內嵌的<value type='...' >...</value>中type屬性
    -->
    <xsd:complexType name="entryType">
        <xsd:sequence>
            <xsd:element ref="key" minOccurs="0"/>
            <xsd:group ref="collectionElements"/>
        </xsd:sequence>
        <xsd:attribute name="key" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	Each map element must specify its key as attribute or as child element.
	A key attribute is always a String value.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="key-ref" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a to a "key" element with a nested
	"<ref bean='...'/>".
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="value" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<value>...</value>"
	element.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="value-ref" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a nested "<ref bean='...'/>".
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="value-type" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[
	A short-cut alternative to a 'type' attribute on a nested
	"<value type='...' >...</value>" element.
				]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <!-- 'props' collection type -->
    <xsd:complexType name="propsType">
        <xsd:complexContent>
            <xsd:extension base="collectionType">
                <xsd:sequence>
                    <xsd:choice minOccurs="0" maxOccurs="unbounded">
                        <xsd:element ref="prop"/>
                    </xsd:choice>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- simple internal types -->
    <xsd:simpleType name="defaultable-boolean">
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="default"/>
            <xsd:enumeration value="true"/>
            <xsd:enumeration value="false"/>
        </xsd:restriction>
    </xsd:simpleType>

</xsd:schema> 

下面我們自定義schema及相應的NamesepaceHandler來擴展Spring:

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.miracle.com/entity/schema/people"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            targetNamespace="http://www.miracle.com/entity/schema/people"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">

    <!--注意這裏需要引入spring beans的名稱空間, 從而使用base="beans:identifiedType"-->
    <xsd:import namespace="http://www.springframework.org/schema/beans" />
    <!--定義了一個名稱爲people的元素,它含有兩個屬性, name和age
        注意:引入了spring beans名稱控件,使用了spring的base擴展後,這裏會默認引入id屬性
    -->
    <!--
        我們可以看一下identifiedType中的內容:其實就是一個包含了名爲id的屬性
        <xsd:complexType name="identifiedType" abstract="true">
            <xsd:attribute name="id" type="xsd:string">
        </xsd:attribute>
    </xsd:complexType>
    -->

    <xsd:element name="people">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="name" type="xsd:string" />
                    <xsd:attribute name="age" type="xsd:int" />
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

編寫實體類(省略:注意實體類應該有三個屬性:id,name和age)和BeanDefinitionParser以及BeanNamespaceHandler:

package com.spring.xml;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;

public class PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

    @Override
    protected Class<?> getBeanClass(Element element) {
        return People.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {

        String id = element.getAttribute("id");
        String name = element.getAttribute("name");
        String age = element.getAttribute("age");
        System.out.println(element.getNodeName());

        builder.addPropertyValue("id", id).addPropertyValue("name", name).addPropertyValue("age", age);
    }
}
package com.spring.xml;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class PeopleNameSpaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {

        registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser());
    }
}

application.xml配置文件及測試類:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:entity="http://www.miracle.com/entity/schema/people"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.miracle.com/entity/schema/people http://www.miracle.com/entity/schema/people.xsd">
    <!-- 注意這裏的id必須提供,它是bean在容器中的唯一標識,如果不提供則容器會拋出異常 -->
    <entity:people id="people" name="123" age="123"/>

</beans>
package com.spring.xml;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;

public class PeopleTest {


    @Test
    public void test() {

        ApplicationContext ioc = new ClassPathXmlApplicationContext("application.xml");
        People people = (People) ioc.getBean("people");

        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        System.out.println(Arrays.asList(beanDefinitionNames));
        System.out.println(people);
    }
}

基本的spring schema文件分析就到這裏了。
原本的計劃是寫一個比較複雜的自定義schema出來,但因爲寫的過程中出現了很多異常,所以決定暫時放棄,後續再來補充。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章