了解更多技术文章请点击原文链接
前言
尽管使用了Dubbo许久,但其实对于其了解还是九牛一毛,上个月通读了Netty实战(粗略的了解),突然有了解读Dubbo源码的欲望,时不待我,那就赶紧开始吧。
熟悉Dubbo的朋友,可能都知道其采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
当然,如果你不想使用Spring配置,而希望通过API的方式进行调用,Dubbo也是支持的,但是官方是不推荐的(原因你猜)。
今天,就跟大家聊一聊Dubbo是如何基于Schema实现的。
准备
具体实现,需要使用到一下几个配置或者是类:
spring.handlers:解析所使用的类
spring.schemas:自定义标签的路径
DubboNamespaceHandler.Java:处理器
DubboBeanDefinitionParser.java:解析器
xxxxConfig.java:JavaBean建模
实现
这里我们以dubbo:application做案例介绍
实体类ApplicationConfig.java
位于com.alibaba.dubbo.config包下,截取部分代码:
public class ApplicationConfig extends AbstractConfig {
private static final long serialVersionUID = 5508512956753757169L;
private String name;
private String version;
private String owner;
private String organization;
private String architecture;
private String environment;
private String compiler;
private String logger;
private List registries;
private MonitorConfig monitor;
private Boolean isDefault;
public ApplicationConfig() {
}
public ApplicationConfig(String name) {
setName(name);
}
编写dubbo.xsd文件
位于META-INF下,截取部分代码:
关于xsd:schema的各个属性具体含义就不作过多陈述,大家可以参见
http://www.w3school.com.cn/schema/schema_elements_ref.asp
DubboBeanDefinitionParser和DubboNamespaceHandler实现解析
DubboNamespaceHandler会根据schema和节点名找到某个DubboBeanDefinitionParser,然后由DubboBeanDefinitionParser完成具体的解析工作。因此需要分别继承NamespaceHandlerSupport和实现BeanDefinitionParser类。
两个类都位于com.alibaba.dubbo.config.spring.schema包下,以下是DubboNamespaceHandler部分代码:
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
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));
}
}
DubboBeanDefinitionParser由于太长了,大家自行查阅源码。
定制spring.handlers和spring.schemas
编码完毕之后,还需要做一些配置工作。我们必须告诉Spring我们准备使用自定义的标签元素,告诉Spring如何解析元素,否则Spring没那么聪明。这里需要2个配置文件,spring.handlers和spring.schemas(位于META-INF下即可),用于告诉Spring自定义标签的文档结构以及解析它的类。两个文件内容分别如下:
spring.handlers:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
spring.schemas:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
注意 \是转义,一定要加,不然会提示报错。
spring-context-dubbo.xml
好了,最终呈现给大家的就是这个样子: