dubbo泛化调用

本文详细解读Dubbo泛化调用的原理、应用场景和关键API,包括GenericService接口的使用方法,以及如何通过实例化和参数封装进行远程服务调用。适合理解网关服务和测试平台如何利用泛化调用来实现接口抽象和灵活测试。
摘要由CSDN通过智能技术生成

官方文档:泛化调用(客户端泛化) | Apache Dubbo

官方dubbo项目案例:dubbo-samples/dubbo-samples-generic at master · apache/dubbo-samples · GitHub

下载下案例源码,本地启动下zk即可debug调试

使用场景

泛化调用主要用于实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。比如如下场景:

  1. 网关服务:如果要搭建一个网关服务,那么服务网关要作为所有RPC服务的调用端。但是网关本身不应该依赖于服务提供方的接口API(这样会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以需要泛化调用的支持。

  2. 测试平台:如果要搭建一个可以测试RPC调用的平台,用户输入分组名、接口、方法名等信息,就可以测试对应的RPC服务。那么由于同样的原因(即会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以平台本身不应该依赖于服务提供方的接口API。所以需要泛化调用的支持

dubbo泛化调用主要API

com.alibaba.dubbo.config.RegistryConfig; //注册中心配置 com.alibaba.dubbo.config.ApplicationConfig; //应用配置 com.alibaba.dubbo.config.ReferenceConfig; //引用的服务配置(类似reference注解或xml配置) com.alibaba.dubbo.rpc.service.GenericService;//实际调用的服务(泛化服务)
其中com.alibaba.dubbo.rpc.service.GenericService#$invoke是泛化调用方法


其中com.alibaba.dubbo.rpc.service.GenericService#$invoke是泛化调用方法

方法入参分别为方法名称、参数类型数组、入参对象数组

GenericService只有一个方法Object$invoke(String method,String[] parameterTypes,Object[] args)throwsGenericException;invoke接受三个参数,分别为方法名,参数类型组以及参数值组,其中参数类型和参数值一一对应。

GenericService的实例化是通过ReferenceConfig的单例调用方法得到的。ReferenceConfig配置了诸如服务接口名等参数。需要注意的是,在使用泛化调用时,generic属性要置为true

package com.alibaba.dubbo.rpc.service;
public interface GenericService {

    /**
     * Generic invocation
     *
     * @param method         Method name, e.g. findPerson. If there are overridden methods, parameter info is
     *                       required, e.g. findPerson(java.lang.String)
     * @param parameterTypes Parameter types
     * @param args           Arguments
     * @return invocation return value
     * @throws Throwable potential exception thrown from the invocation
     */
    Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}

GenericService的实例化实例化案例:

public static void main(String[] args) throws Exception {
	ApplicationConfig applicationConfig = new ApplicationConfig();
	applicationConfig.setName("generic-call-consumer");
	RegistryConfig registryConfig = new RegistryConfig();
	registryConfig.setAddress("zookeeper://127.0.0.1:2181");
	ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
	referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
	applicationConfig.setRegistry(registryConfig);
	referenceConfig.setApplication(applicationConfig);
	referenceConfig.setGeneric(true);
	referenceConfig.setAsync(true);
	referenceConfig.setTimeout(7000);

	genericService = referenceConfig.get();

}

调用流程:

调用 <-> GenericImplFilter <-> 网络 <-> GenericFilter <-> 服务实现

其中在GenericImplFilter中会在Consumer端,对泛化调用相关参数重新构建和处理,使用invoke.invoke发起调用

 然后会调用服务端的对应的接口和方法,会被GenericFilter拦截

注意:GenericImplFilter并不是GenericFilter的实现,他们两个是Filter接口的实现

参数封装案例:如果是多重对象参数,可以传入json,例如

// 实体类
public class User implements Serializable {
    private static final long serialVersionUID = 4741417427705290705L;
    private String name;
    private int gender;
    //getter & setter & constructor
}

// 实体类
public class PageReq<T> implements Serializable {
    private static final long serialVersionUID = -6720015744986291779L;
    private int pageSize;
    private int pageNum;
    private T queryParam;
	//getter & setter & constructor
}

// 接口
public interface TestGenericService {
    String genericTypeParam(PageReq<User> userReq);
}



// 参数封装,并调用
public static void main(String[] args) {
	//方法名
	String methodName = "genericTypeParam";
	//参数类型
	String[] parameterTypes = new String[1]; //1个参数类型
	parameterTypes[0] = "service.PageReq"; //参数类的全限定名
	//参数对象
	Object[] objectParams = new Object[1]; //1个参数值
	JSONObject paramPage = new JSONObject(); //看作是对象转换为JSONObject的过程
	paramPage.put("pageNum", 10);
	paramPage.put("pageSize", 1);
	JSONObject paramUser = new JSONObject();
	paramUser.put("name", "nicolimine");
	paramUser.put("gender", 1);
	paramUser.put("class", "service.User");//注意这里,PojoUtils解析Map类型,如果存在key=class时,会直接指定该Object类型
	paramPage.put("queryParam", paramUser);
	objectParams[0] = paramPage;
	//执行泛化调用,genericService如何实例化可以参考官方案例
	genericService.$invoke(methodName, parameterTypes, objectParams);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值