背景:在开发mapi的过程中,自以为很了解其中的原理。实际上并不了解,主要是使用了dubbo中的泛型化调用的思想;

 原理总结


什么是泛化调用?

泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。

ps. ​​GenericService​​实际上是​​Dubbo​​提供的通用接口,解决使用通用接口调用任何服务方法

好处:最最直接的表现就是服务消费者不需要有任何接口的实现,就能完成服务的调用。

dubbo泛型化实现的流程:



+-------------------------------------------+               +-------------------------------------------+
| consumer 端 | | provider 端 |
| | | |
| | | |
| | | |
| | | |
| +------------------+ | | +--------------+ |
| |GenericImplFilter | | Invocation | |GenericFilter | |
| +----> | +-------------------------> | | |
| | +------------------+ | | +--------------+ |
| +-----------+ | | | +-----------+ |
| | | | | | | | |
| |Client | | | +--> | Service | |
| | | | | | | |
| +-----------+ | | +-------+---+ |
| | | | |
| ^ +------------------+ | | +--------------+ | |
| | |GenericImplFilter | | | |GenericFilter | <----------+ |
| +-------------+ | <-------------------------+ | |
| +------------------+ | | +--------------+ |
| | | |
| | | |
| | | |
| | | |
+-------------------------------------------+ +-------------------------------------------+


GenericFilter: 负责provider端参数的转换.

1、调用时,将hashmap结构的参数转换成对应的pojo

2、返回结果时, 将pojo转换成hashmap



// 调用时
args = PojoUtils.realize(args, params, method.getGenericParameterTypes()
// 返回结果时
return new RpcResult(PojoUtils.generalize(result.getValue()));


 

 

GenericImplFilter: 负责consumer端参数的转换, 将POJO转换成hashmap结构



Object[] args = PojoUtils.generalize(arguments);


 

这样consumer端传过来的只是一个map, 并不要有provider端的jar包, 根据这个就可以实现dubbo接口的测试平台.

 

 

​核心方法:GenericService​​这个接口和java的反射调用非常像, 只需提供调用的方法名称, 参数的类型以及参数的值就可以直接调用对应方法了.



package com.alibaba.dubbo.rpc.service;

/**
* 通用服务接口
*
* @author william.liangf
* @export
*/
public interface GenericService {

/**
* 泛化调用
*
* @param method 方法名,如:findPerson,如果有重载方法,需带上参数列表,如:findPerson(java.lang.String)
* @param parameterTypes 参数类型
* @param args 参数列表
* @return 返回值
* @throws Throwable 方法抛出的异常
*/
Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}


PojoUtils 提供了对象和map的序列化和反序列化