一、dubbo服务发布原理图:
根据service中配置的配置文件,如:spring-provider.xml
随着dubbo配置文件的加载,配置文件中的信息就会被dubbo使用,ServiceConfig就会读取到ref(com.xp.UserService),然后通过ProxyFactory去getInvoker()或getProxy()创建一个AbstractProxyInvoker实例(Invoker)。
@Extension("javassist")
public interface ProxyFactory {
//针对client端,创建出代理对象
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker) throws RpcException;
//针对server端,将服务对象如HelloServiceImpl包装成一个Invoker对象
@Adaptive({Constants.PROXY_KEY})
<T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}
Exporter主要是打开socket监听服务,接收客户端的各种请求。(是Invoker的生命周期管理类)
从上面得知服务发布的第一个过程就是:使用ProxyFactory将UserServiceImpl封装成一个本地执行的Invoker。
执行这个服务,即执行这个本地Invoker,即调用这个本地Invoker的invoke(Invocation invocation)方法,方法的执行过程就是通过反射执行了UserServiceImpl的内容。现在的问题是:这个方法的参数Invocation invocation的来源问题。
针对server端来说,Protocol要解决的问题就是:根据指定协议对外公布这个UserService服务,当客户端根据协议调用这个服务时,将客户端传递过来的Invocation参数交给上述的Invoker来执行。所以Protocol加入了远程通信协议的这一块,根据客户端的请求来获取参数Invocation invocation。
先来看下Protocol的接口定义:
@Extension("dubbo")
public interface Protocol {
int getDefaultPort();
//针对server端来说,将本地执行类的Invoker通过协议暴漏给外部。这样外部就可以通过协议发送执行参数Invocation,然后交给本地Invoker来执行
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
//这个是针对客户端的,客户端从注册中心获取服务器端发布的服务信息
//通过服务信息得知服务器端使用的协议,然后客户端仍然使用该协议构造一个Invoker。这个Invoker是远程通信类的Invoker。
//执行时,需要将执行信息通过指定协议发送给服务器端,服务器端接收到参数Invocation,然后交给服务器端的本地Invoker来执行
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
}
- export(Invoker invoker)的过程即根据Invoker中url的配置信息来最终选择Protocol的实现,默认实现是"dubbo"的扩展实现即DubboProtocol,然后再对DubboProtocol进行依赖注入,进行wrap包装。
- 可以看到在返回DubboProtocol之前,经过了ProtocolFilterWrapper、ProtocolListenerWrapper、RegistryProtocol的包装。
- 所谓的包装就是如下类似的内容:
-
package com.alibaba.xxx; import com.alibaba.dubbo.rpc.Protocol; public class XxxProtocolWrapper implemenets Protocol { Protocol impl; public XxxProtocol(Protocol protocol) { impl = protocol; } // 接口方法做一个操作后,再调用extension的方法 public Exporter<T> export(final Invoker<T> invoker) { //... 一些操作 impl .export(invoker); // ... 一些操作 } // ... }
二、dubbo消费原理
1、项目启动以后,随着配置文件Spring-customer.xml加载,ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例(如上图中的红色部分),这是服务消费的关键。
接下来把Invoker转换为客户端需要的接口(如:HelloWorld)
2、用到的主要技术:动态代理,反射技术