dubbo(一)spring schema拓展技术
https://blog.csdn.net/java_zldz_xuws/article/details/84648398
在阐述dubbo原理之前,我先介绍一下dubbo与spring怎么糅合在一块,为什么dubbo标签,spring可以解析以及dubbo spi是什么,这是学习dubbo的第一步,接下来,我们会从源码的角度,进一步解析dubbo如何实现服务暴露,注册,路由,负载均衡,线程模型,mock机制,超时重试,服务发现,启动检查,令牌,优雅关机,协议,序列化,编解码,缓存,泛化,事件 等,欢迎大家指正和学习
Spring提供了可扩展Schema的支持,完成一个自定义配置一般需要以下步骤:
设计配置属性和JavaBean
编写XSD文件
编写NamespaceHandler和BeanDefinitionParser完成解析工作
编写spring.handlers和spring.schemas串联起所有部件
在Bean文件中应用
dubbo中所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。
下面我们就用dubbo为例来看如何实现对Spring配置的标签扩展。(对应的项目我已经上传至github,地址:https://github.com/xuws2gj/spring-schema.git)
1)设计配置属性和JavaBean
2)编写XSD文件
在这里需要注意的是把spring.schemas(http\://www.pomelo.com/schema/people.xsd=META-INF/people.xsd)
xmlns与targetNamespace写上http\://www.pomelo.com/schema/people
3)编写spring.schemas与spring.handlers文件
spring.schemas使用http\://www.pomelo.com/schema/people.xsd帮我们找到对应的xsd项目位置META-INF/people.xsd
spring.handlers定义 http\://www.pomelo.com/schema/people=com.dean.handle.NamespaceHandler,在加载xsd的时候遇到namespace定义加载进入解析标签
4)编写NamespaceHandler
spring加载applicationContext.xml启动过程中,spring解析标签变成bean过程,我们这里不讨论,感兴趣的话
https://blog.csdn.net/fighterandknight/article/details/50126329/,http://www.blogjava.net/heavensay/archive/2013/10/28/405699.html
loadBeanDefinitions
-doLoadBeanDefinitions-registerBeanDefinitions(doc(xml解析成Document对象), resource)
-registerBeanDefinitions(Document doc, Resource resource)
-registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
-parseBeanDefinitions(root, delegate)--这个方法区别了默认标签和自定义标签解析规则
-parseCustomElement(Element ele)
-parseCustomElement(Element ele, BeanDefinition containingBd)-根据元素的命名空间(applicationContext.xml-xmlns:people)经过resolve(namespaceUri) 方法会找META-INF/spring.handlers得到NamespaceHandler
-handler.parse(ele, new ParserContext(this.readerContext, this, containingBd))会找具体实现类(namespaceHandler的parse实现即使用studtentBeanDefinitionParser进行自定义标签解析)
5)编写ApplicationContext.xml
这里需要注意的是xmlns:people定义了namespace---handler
6)编写StudentBeanDefinitionParser
关于spring如何添加新定义的标签和解析标签涉及到 BeanDefinitionParserDelegate,感兴趣的可以-------------------------------------http://blog.51cto.com/dba10g/1726519,https://blog.csdn.net/fighterandknight/article/details/50126329,AbstractBeanDefinitionParser的parse()方法看一下, 可以看到,该处理逻辑中主要是获取当前标签中定义的name和age属性的值,然后将其按照一定的处理逻辑注册到当前的BeanDefinition中。这里还实现了一个getBeanClass()方法,该方法用于表明当前自定义标签对应的BeanDefinition所代表的类的类型
对自定义配置文件的解析,但是我们可以看到,在这个函数中大部分的来处理将解析后的AbstractBeanDefinition转换为BeanDefinitionHolder并注册的功能,而真正去做解析的事情委托了给parseInternal,真是这句代码调用了我们的自定义解析函数doParse()。在parseInternal中,并不是直接调用自定义的doParse函数,而是惊醒了一些列的数据准备,包括对beanClass,scope,lazyInit等
7)编写SchemaTest
总结 dubbo自定义标签使用了spring-schema,dubbo配置标签与spring完成融合 dubbo源码dubbo-config下的dubbo-spring有对应的实现过程,原理类似,即定义属性,xsd,handler,dubboBeanDefinitionParser等完成