zoukankan      html  css  js  c++  java
  • Spring如何解析Dubbo标签

      1. 要了解Dubbo是如何解析标签的,首先要清楚一点就是Spring如何处理自定义标签的,因为Dubbo的标签可以算是Spring自定义标签的一种情况;

      2. Spring通过两个接口来解析自定义的标签:NamespaceHandlerBeanDefinitionParser接口;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

  • 相关阅读:
    Ansible 详细用法说明(一)
    Puppet基于Master/Agent模式实现LNMP平台部署
    推荐-zabbix原理篇
    Centos 6.x 安装Nagios及WEB管理nagiosql实现windows及linux监控指南
    CentOS 7下安装Logstash ELK Stack 日志管理系统(下)
    【Python基础学习二】定义变量、判断、循环、函数基本语法
    【Python基础学习一】在OSX系统下搭建Python语言集成开发环境 附激活码
    内联函数
    2016 科大讯飞校招研发一面二面 10.13
    hiho #1151 : 骨牌覆盖问题·二 (递推,数论)
  • 原文地址:https://www.cnblogs.com/xiaozhang2014/p/7821104.html
Copyright © 2011-2022 走看看