基于dubbo-2.7.8进行分析。
1. 原理
dubbo利用Spring XML schema扩展机制,自定义了一套配置,存储在文件dubbo.xsd中。dubbo.xsd文件用来约束使用XML配置时的标签和对应的属性, 比如Dubbo中的<dubbo:service>
和〈dubbo:reference〉
标签等
Spring 在解析到自定义的 namespace 标签时(比如<dubbo:service>标签),会查找对应的spring.schemas和spring.handlers文件, 最终触发Dubbo的DubboNamespaceHandler类来进行初始化和解析。 至于Spring具体是如何解析的,可以参考Spring源码BeanDefinitionParserDelegate#parseCustomElement(Element, BeanDefinition)
会有以下两个文件:
// spring,schemas 文件
http\://dubbo.apache.org/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/compat/dubbo.xsd
// spring.handlers 文件
http\://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNa
mespaceHandler
http\://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.Dub
boNamespaceHandler
spring.schemas文件指明约束文件的具体路径, spring, handlers文件指明
DubboNamespaceHandler类来解析标签
2. xml解析
解析逻辑入口是在DubboNamespaceHandler
类中完成。
如图所示,DubboNamespaceHandler主要把不同的标签通过registerBeanDefinitionParser
方法关联至各自的解析实现类DubboBeanDefinitionParser
中。而其中的parse方法就是具体的解析逻辑。
主要分为两步,注册Bean和解析标签追加属性
2.1 注册bean
这一段的逻辑主要负责把标签解析成对应的Bean定义并注册到Spring 上下文中,同时保证了 Spring容器中相同id的Bean不会被覆盖。
2.2 解析标签
这一段主要是对<dubbo:service>/<dubbo:provider>/<dubbo:consumer>进行解析,通过parseProperties/parseNested方法把属性提取出来,追加到BeanDefinition中,运行时Spring会自动处理注入值。
需要注意一下,〈dubbo:provider〉 和〈dubbo:consumer〉 标签复用了解析代码(parseNested),主要是因为这两个标签都是可以内部嵌套的标签, 比如<dubbo:provider>内部可能嵌套了〈dubbo:service〉。
其实Dubbo只做了属性提取的事情, 运行时属性注入和转换都是Spring处理的。Dubbo框架生成的BeanDefinition最终还是会委托Spring创建对应的Java对象,dubbo.xsd中定义的类型都会有与之对应的POJO