Spring如何解析Dubbo标签
1. 要了解Dubbo是如何解析标签的,首先要清楚一点就是Spring如何处理自定义标签的,因为Dubbo的标签可以算是Spring自定义标签的一种情况;
2. Spring通过两个接口来解析自定义的标签:NamespaceHandler和BeanDefinitionParser接口;NamespaceHandler负责namespace的处理,而BeanDefinitionParser负责Bean的解析;
  3. 我们自定义标签的时候,可以实现NamespaceHandler接口,但更多的是继承NamespaceHandler的抽象类:NamespaceHandlerSupport,然后在classpath的META-INF目录下编写一个spring.handlers文件,在该文件中定义namespace的URL和namespace处理类的映射。
比如Dubbo的spring.handlers文件内容(/是转义):
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
4. spring框架初始化时会加载所有classpath的spring.handlers文件,把namespace的URL和namespace处理类映射到Map中,Spring在解析的时候,遇到一些自定义的标签的时候,会在这个Map中查找namespace处理类,使用这个使用这个自定义的处理类来进行标签的解析工作;
5. 同样,Dubbo框架的namespace的处理类是DubboNamespaceHandler,也是实现了NamespaceHandlerSupport接口来处理命名空间,然后在这个类的初始化的时候给所有标签都注册了各自的解析器;而Dubbo的解析类DubboBeanDefinitionParser同样也是实现了BeanDefinitionParser接口;

DubboNamespaceHandler 源代码如此下:
/**
* DubboNamespaceHandler
*
* @author william.liangf
* @export
*/
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));
} }
可以看到,Dubbo有10个标签,每个标签会解析到对应的实体上,每个实体中的属性对应标签中的属性,比如ApplicationConfig类:
/**
* ApplicationConfig
*
* @author william.liangf
* @export
*/
public class ApplicationConfig extends AbstractConfig { private static final long serialVersionUID = 5508512956753757169L; // 应用名称
private String name; // 模块版本
private String version; // 应用负责人
private String owner; // 组织名(BU或部门)
private String organization; // 分层
private String architecture; // 环境,如:dev/test/run
private String environment; // Java代码编译器
private String compiler; // 日志输出方式
private String logger; // 注册中心
private List<RegistryConfig> registries; // 服务监控
private MonitorConfig monitor; // 是否为缺省
private Boolean isDefault; public ApplicationConfig() {
} public ApplicationConfig(String name) {
setName(name);
} @Parameter(key = Constants.APPLICATION_KEY, required = true)
public String getName() {
return name;
} public void setName(String name) {
checkName("name", name);
this.name = name;
if (id == null || id.length() == 0) {
id = name;
}
} @Parameter(key = "application.version")
public String getVersion() {
return version;
} public void setVersion(String version) {
this.version = version;
} public String getOwner() {
return owner;
} public void setOwner(String owner) {
checkMultiName("owner", owner);
this.owner = owner;
} public String getOrganization() {
return organization;
} public void setOrganization(String organization) {
checkName("organization", organization);
this.organization = organization;
} public String getArchitecture() {
return architecture;
} public void setArchitecture(String architecture) {
checkName("architecture", architecture);
this.architecture = architecture;
} public String getEnvironment() {
return environment;
} public void setEnvironment(String environment) {
checkName("environment", environment);
if(environment != null) {
if (! ("develop".equals(environment) || "test".equals(environment) || "product".equals(environment))) {
throw new IllegalStateException("Unsupported environment: " + environment + ", only support develop/test/product, default is product.");
}
}
this.environment = environment;
} public RegistryConfig getRegistry() {
return registries == null || registries.size() == 0 ? null : registries.get(0);
} public void setRegistry(RegistryConfig registry) {
List<RegistryConfig> registries = new ArrayList<RegistryConfig>(1);
registries.add(registry);
this.registries = registries;
} public List<RegistryConfig> getRegistries() {
return registries;
} @SuppressWarnings({ "unchecked" })
public void setRegistries(List<? extends RegistryConfig> registries) {
this.registries = (List<RegistryConfig>)registries;
} public MonitorConfig getMonitor() {
return monitor;
} public void setMonitor(MonitorConfig monitor) {
this.monitor = monitor;
} public void setMonitor(String monitor) {
this.monitor = new MonitorConfig(monitor);
} public String getCompiler() {
return compiler;
} public void setCompiler(String compiler) {
this.compiler = compiler;
AdaptiveCompiler.setDefaultCompiler(compiler);
} public String getLogger() {
return logger;
} public void setLogger(String logger) {
this.logger = logger;
LoggerFactory.setLoggerAdapter(logger);
} public Boolean isDefault() {
return isDefault;
} public void setDefault(Boolean isDefault) {
this.isDefault = isDefault;
} }
Dubbo版本:2.8.4.5
Spring如何解析Dubbo标签的更多相关文章
- Dubbo原理和源码解析之标签解析
		一.Dubbo 配置方式 Dubbo 支持多种配置方式: XML 配置:基于 Spring 的 Schema 和 XML 扩展机制实现 属性配置:加载 classpath 根目录下的 dubbo.pr ... 
- 6.2  dubbo在spring中自定义xml标签源码解析
		在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ... 
- 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程
		原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ... 
- 《spring源码解读》 - IoC 之解析 import 标签
		在上一文中我们分析了注册 BeanDefinition 的过程,在其中我们了解到在解析跟节点和子节点时分两种情况,对于默认名称空间的标签我们通过 DefaultBeanDefinitionDocume ... 
- 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)
		该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ... 
- 6.1  如何在spring中自定义xml标签
		dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ... 
- Spring事务解析3-增强方法的获取
		从InfrastructureAdvisorAutoProxyCreator的层次结构中可以看到,InfrastructureAdvisorAutoProxyCreator间接实现了SmartInst ... 
- Spring Cloud和Dubbo整合开发笔记(1)
		一.需求背景: 公司内部老项目微服务技术栈使用Dubbo, 新项目技术栈使用主流的Spring Cloud相关组件开发,新旧项目涉及交互调用,无法直接通信数据传递. 老项目基于Dubbo,重构代码升级 ... 
- 08.Spring Bean 解析 - BeanDefinitionDocumentReader
		基本概念 BeanDefinitionDocumentReader ,该类的作用有两个,完成 BeanDefinition 的解析和注册 . 解析:其实是解析 Ddocument 的内容并将其添加到 ... 
随机推荐
- Round 403 div. 2
			B 可以二分相遇的坐标:也可以二分时间,判断是否存在两个人的区间没有交. An easy way to intersect a number of segments [l1, r1], ..., [l ... 
- 【原创】【目录】实现rich editor(富文本编辑器)教程,深入理解selectiona/range操作与浏览器差异
			日常工作中,接触富文本编辑的次数还是很多,特发此教程,希望可以改变富文本编辑的技术门槛较高的现状,解决这部分的坑. 前提准备,兼容获取range,统一回车行为,前期准备工作 了解document.ex ... 
- LibreOJ #539. 「LibreOJ NOIP Round #1」旅游路线(倍增+二分)
			哎一开始看错题了啊T T...最近状态一直不对...最近很多傻逼题都不会写了T T 考虑距离较大肯定不能塞进状态...钱数<=n^2能够承受, 油量再塞就不行了...显然可以预处理出点i到j走c ... 
- Qt ------ 断开某对信号与槽的connect
			QMetaObject::Connection dis; dis = connect(this,&TcpSocket::readyRead,this,&TcpSocket::readD ... 
- phpstorm改变文件编码由utf变为gbk
			PhpStorm是一个轻量级且便捷的PHP IDE,其旨在提供用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查. 由于PHPStorm编辑器默认是UTF-8编码 如果开发的是 ... 
- 线程函数对比 win/linux
			原文 
- VisualSVN 5.1.4破解
			1. 备份visualSVNbin目录 2. 打开VS命令提示工具,反编译VisualSVN.Core.L.dll 运行命令 ildasam "VisualSVN安装目录\bin\Visua ... 
- Java设计模式の模版方法模式
			概述 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的 ... 
- 解决VS Code编译调试中文输出乱码
			最近尝试用VS Code配置了C和C++的编译调试环境,结果遇到了中文输出乱码问题,查阅网上竟然还没有相关问题,有怀疑是mingw中文支持问题,但最后证明是VS Code编码问题. 解决方案: 文件- ... 
- 对拍 bat
			:loop maker.exe std.exe my.exe fc std.out my.out goto loop pause 
