上一篇讲到了Dubbo中不得不说的SPI机制,链接为 Dubbo源码解析 一、Dubbo的SPI机制 ,这一节将会讲到Dubbo中Consumer的启动过程。
下面以xxxxConsumer启动的过程为例。
我认为Consumer的启动主要分为两个方面:
1、如何根据要实现的接口注入到Spring服务中
2、如何根据实现的consumer接口、调用的方法、调用的参数值来实现代理
下面以DemoService为例:
public interface DemoService {
String sayHello(String name);
}
对应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">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:application name="demo-consumer"/>
<!-- use multicast registry center to discover service -->
<!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<dubbo:registry group="providertest" protocol="zookeeper" address="127.0.0.1:2181" />
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
local regular interface -->
<dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>
在xml中,我们主要看 <dubbo:reference> 这个节点的实现,我们第一步关注的即为如何生成demoService的代理对象,有了这个代理对象,我们就可以像使用本地实现一样,使用demoService。
我们之前解析过Spring启动代码,知道Spring启动时会先获取到bean的定义,之后在根据bean的定义去生成bean。链接为 Spring 源码剖析 二、主要逻辑代码赏析之获取bean的定义。dubbo也不例外,<dubbo:reference>肯定会生成对应的一个对应的beanDefinition,我们看一下其源码:
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
@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());
}
}
可以看到reference对应的节点解析类型为 D