spring是大家熟悉的,而且经常用到的一个成熟框架,通过spring可以将对象的创建交给框架,从而实现解耦。Spring有两大重要的特性:IoC,AOP。IoC是依赖注入,AOP是面向切面编程。
dubbo中是如何运用spring的呢?
dubbo中关于spring的运用主要在dubbo-config-spring包。打开该包,发现也就8个类,这篇博客主要讲解DubboBeanDefinitionParser、DubboNamespaceHandler。另外的三个类Service
Bean、ReferenceBean、AnnotationBean在叙述上面两个类的时候会涉及到,其他的类这里暂不讨论。
看dubbo的spring配置发现,其中的有些节点以dubbo:service dubbo:application开头。其实这是dubbo扩展了spring。下面分析dubbo是怎样扩展运用spring与自己的配置结合起来的。
DubboBeanDefinitionParser类:
public class DubboBeanDefinitionParser implements BeanDefinitionParser
上面是DubboBeanDefinitionParser类的定义,DubboBeanDefinitionParser类实现了BeanDefinitionParser,查看spring的源码会发现BeanDefinitionParser接口用于解析xml文件中的配置,然后将配置转化为java模型。解析通过实现parse方法实现,在parse方法主要完成element对象的解析,同时将解析的属性转化到beanDefinition中,具体解析逻辑就不叙述。
DubboBeanDefinitionParser类用于解析,那解析过程中是怎样找到该类的,为什么不是其他的BeanDefinitionParser。这就要看DubboNamespaceHandler类。
DubboNamespaceHandler类:
public class DubboNamespaceHandler extends NamespaceHandlerSupport
DubboNamespaceHandler类继承了NamespaceHandlerSupport类,DubboNamespaceHandler类就一个init方法。
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
}
上面是init方法,其实init方法很简单,就是将节点与对应的解析器进行映射,这也就是为什么出现dubbo:service的时候,就会是DubboBeanDefinitionParser了。我们发现上面DubboBeanDefinitionParser第一个参数都是一个class,其实这个class就到时创建的对象,也就是说xml中service节点里面的描述会转化到servicebean,reference就对应ReferenceBean,annotation对应AnnotationBean。
那spring在解析过程中又是怎么找到DubboNamespaceHandler?同时我们知道xml都有一套规范,那dubbo又是运用了怎么的原理来让自己符合spring的规范的呢。
这里需要查看resources文件夹,在resources文件夹里面有dubbo.xsd spring.handlers spring.schemas
dubbo.xsd:就是一套dubbo的xml定义规范
spring.handlers:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
这是spring.handlers里面的内容,就是建立映射,通过他找到DubboNamespaceHandler。
spring.schemas:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
这个文件指定了xsd文件来自哪里。
这篇博客只是大体介绍了一下dubbo是如何运用spring的扩展标签的,其实运用spring的扩展标签可以在很多地方见到,spring框架内部就能见到,例如AOP里面有AOPNamespaceHandler用于对aop一些标签的定制其实特定化。