Dubbo系列之Dubbo 服务暴露

1、Dubbo配置解析

1.1 配置解析

首先理解一个配置文件中元素的含义:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
       
    <dubbo:protocol name="dubbo"/>

    <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>
    
<beams/>
  1. xmlns:dubbo : 声明前缀为dubbo的命名空间,后面的链接是赋予dubbo一个唯一的名字。他的值与xsi:schemaLocation中指定的第二个值http://dubbo.apache.org/schema/dubbo/dubbo.xsd相关,是里面的targetNamespace,如果他们的值不一致,编译会抛出异常
Caused by: org.xml.sax.SAXParseException; systemId: http://dubbo.apache.org/schema/dubbo/dubbo.xsd; lineNumber: 6; columnNumber: 68; TargetNamespace.1: 应为名称空间 'dubbo', 但方案文档的目标名称空间为 'http://dubbo.apache.org/schema/dubbo'

除此之外,也需要与META-INF/下的spring.handler中的key相对应,指定当遇到这类命名空间时,Spring使用指定的Handler去加载该配置,如果不一致会抛出异常:

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://dubbo.apache.org/schema/dubbo]
  1. xmlns : 什么一个默认的命名空间,所有没有带前缀的元素,都会默认使用这个命名空间
  2. xsi:schemaLocation : 这个需要搭配命名空间使用。前面的http://dubbo.apache.org/schema/dubbo代表一个命名空间的名称,后面的http://dubbo.apache.org/schema/dubbo/dubbo.xsd代表供命名空间使用的XML schema的位置
  3. 对于里面的元素,比如<dubbo:protocol />则会使用到dubbo对应的xsd -> http://dubbo.apache.org/schema/dubbo/dubbo.xsd; 对应里面的protocol,具体的元素类型,对应里面的type属性指定的值。

1.1.1 基于schema设计解析

在Dubbo-config-spring下,有一个dubbo.xsd用于约束使用XML配置时的标签和对应的属性。Spring在解析到对应的一个命名空间的时候,会去spring.handlers和spring.schemas两个文件中,查找对应的一个Handler,用于解析对应的XML配置信息。例如

http\://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
http\://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler

当spring遇到http://dubbo.apache.org/schema/dubbo的时候,会使用DubboNamespaceHandler进行解析。

1.1.2 基于XML配置原理解析

从上面可知,XML的配置的约束的dubbo.xsd的作用,以及他的解析Handler。

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("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
        registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
        registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.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 AnnotationBeanDefinitionParser());
    }

这一块主要是Spring的XML的解析逻辑,会将对应的一个element交给指定的一个Parser进行解析,会保存到一个map里面,以后遇到该element的时候,就使用对应的一个Parser进行解析。
解析的步骤

  1. 替换Id里面的占位符信息,得到一个ID
  2. 如果ID为空,则根绝名字生成ID,如果名字也为空,则使用类的名称
  3. 判断当前的容器中,是否存在一个相同的ID,存在的话,则抛出异常,不存在则注册该bean的信息
  4. 并设置propertyValue的值,添加ID信息
  5. 根据元素不同的类型,去解析不同的配置信息
  6. 找出xml中配置的所有的参数,并放入到beanDefinition中property中

1.1.3 基于注解配置原理解析

1.1.3.1 @EnableDubbo

EnableDubbo注解的作用是启用Dubbo的服务,当Spring在启动初始化的时候,会获取到对应配置头上的注解信息。在@EnableDubbo注解的头部,有两个注解比较重要@EnableDubboConfig和@DubboComponentScan。这两个注解中分别包含了一个@Import注解。

  • @EnableDubboConfig
@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
   

    /**
     * It indicates whether binding to multiple Spring Beans.
     *
     * @return the default value is <code>true</code>
     * @revised 2.5.9
     */
    boolean multiple() default true;

}

@Import注解中的值DubboConfigConfigurationRegistrar实现了ImportBeanDefinitionRegistrar,Spring容器在加载的时候会去加载@Import注解,并且执行其中值指定的类中的registerBeanDefinitions方法。

private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
			throws IOException {
   

	if (visited.add(sourceClass)) {
   
		for (SourceClass annotation : sourceClass.getAnnotations()) {
   
			String annName = annotation.getMetadata().getClassName();
			if (!annName.startsWith("java") && !annName.equals(Import.class.getName())) {
   
				collectImports(annotation, imports, visited);
			}
		}
		imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
	}
}

对去递归的遍历所有的注解,如果注解的名称不是Import并且不是java开头的,则都会进行遍历。然后会去执行registerBeanDefinitions方法。

public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
   

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
   

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));

        boolean multiple = attributes.getBoolean("multiple");

        // Single Config Bindings
        registerBeans(registry, DubboConfigConfiguration.Single.class);
        // 配置的值是以dubbo.xxxs开头的,可以根据Multiple中的注解判断。其主要作用的是Multiple中的注解
        if (multiple) {
    // Since 2.6.6 https://github.com/apache/dubbo/issues/3193
            registerBeans(registry, DubboConfigConfiguration.Multiple.class);
        }

        // 将一些配置相关的Bean都注册到Spring容器中
        // Since 2.7.6
        registerCommonBeans(registry);
    }
}

当设置为multiple的时候,例如dubbo.applations.name1.test1=test1Value会在加载ApplicationConfig的时候,name1会作为bean的名称,注入到容器中,test1/test1Value会作为keyValue的值,保存到BeanDefination中的attribute中。当有多个配置中心的时候,即可使用。

  • @DubboComponentScan
    Dubbo注解的扫描。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值