dubbo泛化调用
泛化调用
泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过 GenericService 调用所有服务实现。(摘自:https://dubbo.apache.org/zh/docs/advanced/generic-reference/)
基础用法:
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zk.xxx.com:2181");
registry.setProtocol("zookeeper");
registry.setGroup("xxx/xxx/xxx");
ApplicationConfig applicationConfig = new ApplicationConfig("appCode");
// 引用远程服务
// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
// 弱类型接口名
reference.setInterface("xxx.xxx.xxxService");
reference.setVersion("1.0.0");
// 声明为泛化接口
reference.setGeneric(true);
reference.setApplication(applicationConfig);
reference.setRegistry(registry);
reference.setRetries(1);
reference.setTimeout(5000);
// 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
GenericService genericService = reference.get();
// 基本类型以及Date,List,Map等不需要转换,直接调用
Object result = genericService.$invoke("getUser", new String[] {
"java.lang.String"},
new Object[] {
"zhangsan"});
System.out.println(result);
原理分析:
- dubbo服务发现流程:https://dubbo.apache.org/zh/docs/concepts/service-discovery/
我们重点看下第四步,消费端想提供者发起的是invoke调用,那什么是invoke调用呢?什么又是invoker? - invoker
mInvoker是Dubbo的核心模型,是Dubbo中的实体域,也就是真实存在的。其他模型都向它靠拢或转换成它,它也就代表一个可执行体,可向它发起invoke调用。在服务提供方,Invoker用于调用服务提供类。在服务消费方,Invoker用于执行远程调用。
生产者暴露服务流程总体分为两步,第一步是接口实现类转换为Invoker,第二步是Invoker转换为Exporter并放入ExporterMap,暴露服务流程图如下:
生产者通过ProxyFactory.getInvoker创建Invoker(AbstractProxyInvoker):
public class JdkProxyFactory extends AbstractProxyFactory {
@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
// proxy为被代理对象 -> xxx.xxx.xxxService
Method method = proxy.getClass().getMethod