服务引用入口
Dubbo利用DubboNamespaceHandler在Spring中对自己的xml配置的命名空间进行解析,其中将服务引用相关配置解析到ReferenceConfig中,为了使用Spring的IOC容器,Dubbo又定义了一个ReferenceBean继承自ReferenceConfig。
ReferenceBean实现了Spring的FactoryBean接口,Spring会调用其getObject()方法将返回的bean注入IOC容器中,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public Object getObject() throws Exception { // get()为其父类ReferenceConfig中的方法 return get(); }
// ReferenceConfig中的get()方法实现 public synchronized T get() { if (destroyed){ throw new IllegalStateException("Already destroyed!"); } if (ref == null) { // 服务引用初始化入口 init(); } return ref; }
|
其中ref为要调用接口的代理类,init()方法中对创建代理并为ref赋值返回。
服务消费者配置案例
1 2 3 4 5 6 7 8
| <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="consumer"/>
<!-- 使用zk注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181/"/>
<!-- 生成远程服务代理,可以和本地bean一样使用demoService --> <dubbo:reference id="echoService" interface="com.netease.dubbo.service.EchoService" check="false"> </dubbo:reference>
|
init()方法伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 通过注册中心
// 1. 获取所有注册中心URL,并添加refer_key,即要引用的服务的配置信息 List<URL> us = loadRegistries(false); if (us != null && us.size() > 0) { for (URL u : us) { // map为要拼接到URL的公共参数 // urls存放拼接refer_key后的注册中心url urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map))); } } // 2. 用refprotocol从注册中心获取获取引用服务的invoker invoker = refprotocol.refer(interfaceClass, urls.get(0));
// 3. 根据invoker创建要调用接口服务的代理 ref = (T) proxyFactory.getProxy(invoker);
|
服务消费者代码中使用
1 2 3 4
| // 从Spring的IOC容器中自动注入一个代理实现 // 此处EchoService为ReferenceBean的getObject()方法返回的代理 @Autowired private EchoService echoService;
|
- 此处代理创建有两种方式:javassist和jdk,下文以jdk代理为例。
使用jdk创建代理时,需要传入一个java.lang.reflect.InvocationHandler的实现类,dubbo中为InvokerInvocationHandler,创建代理时将invoker传递进了InvokerInvocationHandler。
通过该代理对象调用某方法时,都会执行InvocationHandler的invoke()方法,该方法中通过调用invoker对象的invoke()执行rpc远程调用,调用时将调用参数封装成RpcInvocation对象作为Invoker对象的invoke()方法参数,执行完毕返回结果。
服务引用总结
- 从注册中心引用服务,通过Protocol的refer()创建出Invoker对象
- 使用ProxyFactory的getProxy()创建出一个接口的代理对象,该代理对象的方法的执行都交给上述Invoker来执行
以上两步具体过程,请看解析2