WebX主要對Spring解析自定義的命名空間Element元素的邏輯上做了擴(kuò)展。其中最重要的實(shí)現(xiàn)類ConfigurationPointImpl繼承自NamespaceHandlerSupport,即實(shí)現(xiàn)了NamespaceHandler接口。
在Spring中,通過META-INF/spring.handlers文件找到namespaceURI到NamespaceHandler的map,而WebX中的springext則自定義了XmlBeanDefinitionReader中的EntityResolver(SchemaEntityResolver)和NamespaceHandlerResolver(ConfigurationPointNamespaceHandlerResolver)實(shí)例。
其中在SchemaEntityResolver中,先從傳入的SpringExtSchemaSet中查找傳入的namespaceURI對應(yīng)的,如果能存在,則使用找到的Schema實(shí)例構(gòu)建InputSource,否則使用Spring默認(rèn)提供的PluggableEntityResolver。
在ConfigurationPointNamespaceHandlerResolver中,它使用SpringExtSchemaSet中獲取的ConfigurationPoints查找傳入的namespaceURI對應(yīng)的ConfigurationPoint,如果有找到則使用該ConfigurationPoint中的NamespaceHander(一般就是它自己),否則使用Spring默認(rèn)提供的DefaultNamespaceHandlerResolver,即從META-INF/spring.handlers讀取映射關(guān)系。所以SpringExtSchemaSet是WebX中的springext最關(guān)鍵實(shí)現(xiàn),也是它所謂的擴(kuò)展點(diǎn)所在,并且它和Spring是完全兼容的。
進(jìn)一步的,SpringExtSchemaSet的關(guān)鍵實(shí)現(xiàn)是如何從當(dāng)前classpath中找到所有namespaceURI到Schema的映射,以及如何找到每個(gè)自定義的Element tag名到自定義的BeanDefinitionParser的映射。SpringExtSchemaSet通過兩個(gè)類來實(shí)現(xiàn)這些功能:ConfigurationPoints(ConfigurationPointsImpl)和SpringPluggableSchemas。
其中ConfigurationPointsImpl查找classpath內(nèi)所有的META-INF/spring.configuration-points文件,根據(jù)文件的內(nèi)容創(chuàng)建ConfigurationPoint,該文件為key=value的properties文件,其中key為所有子自定義命名空間的xsd文件夾路徑,value格式為:
namespaceURI; defaultElement=<elment-tag>; nsPrefix=<prefix>
如: services/pipeline/valves=http://www.alibaba.com/schema/services/pipeline/valves; defaultElement=valve; nsPrefix=pl-valves
因?yàn)镃onfigurationPoint也是一個(gè)NamespaceHandler(繼承自NamespaceHandlerSupport),因而它需要實(shí)現(xiàn)init()方法,并在init()方法中注冊每個(gè)自定義Element tag到BeanDefinitionParser的映射。ConfigurationPoint支持三種類型的Contribution:.bean-definition-parsers、.bean-definition-decorators、*.bean-definition-decorators-for-attribute,分別對應(yīng)META-INF目錄下的services-pipeline-valves.bean-definition-parsers、services-pipeline-valves.bean-definition-decorators、services-pipeline-valves.bean-definition-decorators-for-attribute,其中services-pipeline-valves是spring.configuration-points文件中的key('/'替換成'-')。這些文件中的key為XML文件中的自定義的Element tag,value為BeanDefinitionParser或BeanDefinitionDecorator。每個(gè)文件抽象成一個(gè)Contribution實(shí)例,在Contribution中查找創(chuàng)建對應(yīng)的Schema類(xsd文件),查找路徑為configurationPointName/contributionName。最后注冊defaultElement(如:valve)到DefaultElementDefinitionParser的映射,它可以解析一個(gè)正常的Bean定義(除了Element tag不是bean),或者一個(gè)Bean引用,如:<valve ref="myValve" />
最后SpringPluggableSchemas則從META-INF/spring.schemas讀取namespaceURI到xsd文件路徑的映射,并轉(zhuǎn)換成本地xsd文件,以及META-INF/spring.handlers中讀取所有自定義的namespace。從META-INF/spring.tooling文件中讀取默認(rèn)的namespace prefix。