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

原文地址:https://www.cnblogs.com/xiaozhang2014/p/7821104.html