从dubbo启动过程讲起<自定义命名空间>

从dubbo启动过程讲起<自定义命名空间>

作为一个优秀的服务治理框架,dubbo确实有很多值得学习的地方,从今天开始我们就一起来抠一抠dubbo里面的诸多细节。因为dubbo整个框架涉及的知识点很广,这里先不全局得去将dubbo。如果你还没接触过dubbo,相对dubbo先有个初步的认识,可以去dubbo官网先了解下。

友情提醒:后续更新全无章法,完全是想到哪写到哪,当然,写到后面,我也会针对性的做一些总结。不喜勿喷!


在使用dubbo时我们通常习惯通过spring的xml配置来启动。

<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">

    <!-- provider's application name, used for tracing dependency relationship -->
    <dubbo:application name="demo-provider"/>

    <!-- use multicast registry center to export service -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- use dubbo protocol to export service on port 20880 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- service implementation, as same as regular local bean -->
    <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>

    <!-- declare the service interface to be exported -->
    <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

</beans>

这种方式给dubbo使用者体验很赞,但是 dubbo: 这个命名空间是如何定义的呢? spring又是怎么对这些bean进行加载的呢?

原来,spring提供了一个接口

public interface NamespaceHandler {
	void init();
	BeanDefinition parse(Element element, ParserContext parserContext);
	BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext);
}

文档写的很清楚这个接口就是为了帮助处理自定义命名空间用的。
spring在载入BeanDefinition的时候会尝试使用指定的NamespaceHandler来解析bean。对每个node逐级调用parse方法并获取到一个BeanDefinition。当然spring也很友好得提供了一个抽象父类。我们只需要重写init方法将我们的解析器注册上去就行。dubbo也是这么做的 org.apache.dubbo.config.spring.schema.DubboNamespaceHandler

public class DubboNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    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 AnnotationBeanDefinitionParser());
    }

}

重点转移到怎么去实现我们的解析器,解析器的接口如下:

public interface BeanDefinitionParser {
	BeanDefinition parse(Element element, ParserContext parserContext);
}

通过这种方式dubbo的上面这个多的config对象就可以成功依赖spring容器进行初始化了。

到这一步可能你会有些疑惑,spring是如何感知到 DubboNamespaceHandler 的存在的呢?其实,你还需要一个配置才成效 spring是从 META-INF/spring.handlers 这个文件中读取handlerMapping列表的。

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

配置文件的意思是指对应指定的命名空间使用对应的处理器。
命名空间大家应该都比较熟悉了只需要 META-INF/spring.schemas 文件中把自己的xsd文件配置进去就行

http\://dubbo.apache.org/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/compat/dubbo.xsd

总结一下,如果需要在spring中自定义命名空间并完成解析大概需要下面四步:

  • 自定义bean解析器
  • 继承NamespaceHandlerSupport,重写init方法,并将解析器注册。
  • 准备xsd并在META-INF/spring.schemas文件中配置命名空间对应的xsd文件
  • 在META-INF/spring.handlers下配置好命名空间对应的解析器

Demo戳这里

到这里dubbo命名空间下配置成功转化为了spring中的BeanDefinition,下一讲将继续为大家分析讲解dubbo启动过程。

# spring 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×