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 的内容并将其添加到 ...
随机推荐
- 拓展kmp总结
借鉴自:https://blog.csdn.net/dyx404514/article/details/41831947 定义母串S,和子串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长 ...
- jQuery多重事件绑定
1. <a> a标签默认绑定了一个onclick事件,当自己再写一个onclick事件的时候,默认自己写的那个优先执行. 如下程序,先执行(123),然后再发生跳转. <!DOCTY ...
- macvtap介绍
macvtap介绍 传统的linux网络虚拟化技术采用的是tap+bridge方式,将虚拟机连接到虚拟的tap网卡,然后将tap网卡加入到bridge.bridge相当于用软件实现的交换机,这种解决方 ...
- TCP的拥塞控制 (四)
TCP NewReno NewReno是在Reno的基础上,改进了Fast Recovery,主要思想是保证处于network中的packet的总量是饱和的. 在Reno算法中,一个超时会导致相 ...
- 第三周——构建一个简单的Linux系统MenuOS
[洪韶武 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ] 第三周 构建一个 ...
- Redis Scan迭代器遍历操作原理(二)
续上一篇文章 Redis Scan迭代器遍历操作原理(一)–基础 ,这里着重讲一下dictScan函数的原理,其实也就是redis SCAN操作最有价值(也是最难懂的部分). 关于这个算法的源头,来自 ...
- 【agc004C】AND Grid
Portal --> agc004C Description 给你一个\(n*m\)的网格图\(A\),有一些格子是'#',现在要构造出两个新的网格图\(B\)和\(C\)满足: 1.如果\(A ...
- 大自然的搬运工:Ubuntu环境下gedit的一些个简单配置
gedit是Ubuntu默认的文本编辑器,个人觉得还是不错的,用它来编程写一些小的demo也很方便,原谅我比较菜,vim用起来感觉打字速度真的很慢呀. 下面对gedit做一些简单配置,方便编程. 一. ...
- windows环境下封装条件wait和signal
linux 环境有提供好的pthread_cond_wait() 和 phread_signal().pthread_broadcast() windows需要自己封装,利用semophore控制线程 ...
- 009.C++ const使用
1.引例 class complex { public: complex(, ) : re (r), im (i) {} complex& operator += (const complex ...