您的位置:首页 > 编程语言 > Java开发

Spring如何解析Dubbo标签

2017-11-12 10:26 453 查看
  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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: