博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dubbo认识
阅读量:5227 次
发布时间:2019-06-14

本文共 3579 字,大约阅读时间需要 11 分钟。

   Dubbo提供了服务注册、RPC服务调用、调用均衡、服务监控和服务failover等功能

   Dubbo框架中有两个重要角色:(服务)提供者和(服务)消费者,这里为了简单起见,将包含了dubbo提供者或消费者功能的应用模块通称为dubbo客户端

   现在大多数java应用都离不开Spring,所以其他java解决方案,或多或少都会支持在Spring中使用,dubbo也不例外。在我记忆中,凡是想在Spring容器中发挥作用的框架,无非都是提供对应的Spring Bean来注入到Spring容器中,dubbo也一样。在源代码的dubbo-container-spring模块中,唯一的类SpringContainer说明了这一点,它的start()方法直接通过ClassPathXmlApplicationContext来启动Spring容器。有人立马会问,SpringContainer的start()方法由谁调用?答案就是com.alibaba.dubbo.container.Main,它是dubbo的入口,Main类中的main方法将依次调用dubbo内置的Container的start()方法。如果没有配置Spring xml文件的路径,dubbo将会默认采用classpath*:META-INF/spring/*.xml。

   那么问题来了,Spring是如何识别dubbo的那些自定义标签的?Spring为了支持用户自定义类加载到Spring容器,提供了org.springframework.beans.factory.xml.NamespaceHandler接口和org.springframework.beans.factory.xml.NamespaceHandlerSupport抽象类,NamespaceHandler#init方法会在对象的构造函数调用之后、属性初始化之前被DefaultNamespaceHandlerResolver调用。dubbo的DubboNamespaceHandler类正是继承了NamespaceHandlerSupport,其代码实现如下:

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));    }}

   registerBeanDefinitionParser方法有父抽象了类NamespaceHandlerSupport的默认实现,第一个参数是elementName,即元素名称,即告诉Spring你要解析哪个标签,第二个参数是BeanDefinitionParser的实现类,BeanDefinitionParser是Spring用来将xml元素转换成BeanDefinition对象的接口。dubbo的DubboBeanDefinitionParser类就实现了这个接口,负责将标签转换成bean定义对象BeanDefinition。dubbo给其返回的BeanDefinition设置了下列属性:

   beanDefinition.setBeanClass(beanClass);        

   beanDefinition.setLazyInit(false);

   beanDefinition.getPropertyValues().addPropertyValue("id", id);

  如果是dubbo:protocol标签,dubboh还会检查所有已经包含protocol属性的BeanDefinition且protocol属性对应的值是ProtocolConfig对象的bean,将其属性的protocol值设置成当前的bean引用:

  definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));

  如果是dubbo服务提供者的dubbo:service标签,则还会设置ref属性为对应接口class的实现类bean:

  beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));

  有没有人想过,当使用dubbo服务提供者的dubbo:service标签时,如果我既不设置id,也不设置name,则dubbo给它的ServiceBean在Spring容器中定义的ID是什么? 答案就是:

if (generatedBeanName == null || generatedBeanName.length() == 0) {                generatedBeanName = beanClass.getName(); } id = generatedBeanName;  int counter = 2; while(parserContext.getRegistry().containsBeanDefinition(id)) {       id = generatedBeanName + (counter ++);}

     有人就会问,Spring怎么知道你自定义了NamespaceHandlerSupport的实现类?Spring容器会默认加载classpath/META-INF下的spring.handlers和spring.schemas文件,来加载名空间处理器和xsd,所以dubbo-config-spring包下的META-INF目录下就有这两个文件。

转载于:https://www.cnblogs.com/moonandstar08/p/5869995.html

你可能感兴趣的文章
如何解除循环引用
查看>>
android中fragment的使用及与activity之间的通信
查看>>
字典【Tire 模板】
查看>>
jquery的contains方法
查看>>
python3--算法基础:二分查找/折半查找
查看>>
Perl IO:随机读写文件
查看>>
Perl IO:IO重定向
查看>>
转:基于用户投票的排名算法系列
查看>>
WSDL 详解
查看>>
[转]ASP数组全集,多维数组和一维数组
查看>>
C# winform DataGridView 常见属性
查看>>
逻辑运算和while循环.
查看>>
Nhiberate (一)
查看>>
c#后台计算2个日期之间的天数差
查看>>
安卓开发中遇到的小问题
查看>>
ARTS打卡第3周
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
cookies相关概念
查看>>
CAN总线波形中ACK位电平为什么会偏高?
查看>>
MyBatis课程2
查看>>