简单叨叨一下Dubbo是如何自定义标签给spring承载bean的。
Spring通过XML解析程序将其解析为DOM树,通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition。再通过Spring自身的功能对BeanDefinition实例化对象。Dubbo做的只是实现了NamespaceHandler解析成BeanDefinition。
好了,总结起来就这么简单,下面我们具体来看一下。
一、约束文件schema
下面是一个标准的文件头的格式
首先自定义的标签会有一些约束规范,比如我自定义的有哪几种标签,标签里面有哪些属性等等,在XML中每个命名空间都会有一个.xsd的约束文件。
一个约束文件.xsd长得像下面这样
里面限制自定义的标签里面有哪些属性,属性的类型是什么啊这种。
二、spring.handlers和spring.schemas
当spring解析xml时遇到自定义的标签时,会调用 BeanDefinitionParserDelegate.parseCustomElement(...) 方法,如下:
可以看到接下来通过 DefaultNamespaceHandlerResolver.resolve(String namespaceUri) 获得对应的Dubbo处理器。这个namespaceUri就是bubbo的命名空间uri,spring会去查找名字为spring.handlers的文件,里边配置了命名空间对应的handler,如下面:
spring会加载spring.handlers和spring.schemas这两个文件,两个文件长下面这样
❀ spring.schemas:里面指定了该标签的约束文件本地路径,在解析XML文件时将XSD重定向到本地文件,避免在解析XML文件时需要上网下载XSD文件。通过实现org.xml.sax.EntityResolver接口来实现该功能。