美文网首页
dubbo泛化调用

dubbo泛化调用

作者: Zal哥哥 | 来源:发表于2021-07-03 15:11 被阅读0次

为什么要使用泛化调用?

一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服务使用的接口定义和方法定义(还有入参返参类型等等信息,常常还需要基于provider端提供的API),两端才能正常通信调用。

然而存在一种使用场景,调用方并不关心要调用的接口的详细定义,它只关注我要调用哪个方法,需要传什么参数,我能接收到什么返回结果即可,这样可以大大降低consumer端和provider端的耦合性。

所以为了应对以上的需求,dubbo提供了泛化调用,也就是在consumer只知道一个接口全限定名以及入参和返参的情况下,就可以调用provider端的调用,而不需要传统的接口定义这些繁杂的结构。

泛化调用的使用方法

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

以上是dubbo官方定义。

  1. 通过spring方式实现
    在 Spring 配置申明 generic="true":
<dubbo:reference id="barService" interface="com.foo.BarService" generic="true" />

在 Java 代码获取 barService 并开始泛化调用:

GenericService barService = (GenericService) applicationContext.getBean("barService");
Object result = barService.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { "World" });

  1. 通过API方式
import com.alibaba.dubbo.rpc.service.GenericService; 
... 

// 引用远程服务 
// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); 
// 弱类型接口名
reference.setInterface("com.xxx.XxxService");  
reference.setVersion("1.0.0");
// 声明为泛化接口 
reference.setGeneric(true);  

// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用  
GenericService genericService = reference.get(); 

// 基本类型以及Date,List,Map等不需要转换,直接调用 
Object result = genericService.$invoke("sayHello", new String[] {"java.lang.String"}, new Object[] {"world"}); 

// 用Map表示POJO参数,如果返回值为POJO也将自动转成Map 
Map<String, Object> person = new HashMap<String, Object>(); 
person.put("name", "xxx"); 
person.put("password", "yyy"); 
// 如果返回POJO将自动转成Map 
Object result = genericService.$invoke("findPerson", new String[]
{"com.xxx.Person"}, new Object[]{person});
...

  1. 如果参数中对象存在复杂结构(也就是参数类型中某个参数是复杂对象),这时,可以使用map来包入参,入参类型可以通过class属性保留下来,如下:

如果POJO 数据:

Person person = new PersonImpl(); 
person.setName("xxx"); 
person.setPassword("yyy");

可用下面 Map 表示:

Map<String, Object> map = new HashMap<String, Object>(); 
// 注意:如果参数类型是接口,或者List等丢失泛型,可通过class属性指定类型。
map.put("class", "com.xxx.PersonImpl"); 
map.put("name", "xxx"); 
map.put("password", "yyy");

demo举例

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;

public class TestDubboGeneric {
    public static void main(String[] args) {
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        // 当前dubbo consumer的application配置,不设置会直接抛异常
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("xxx_test_service");
        // 注册中心配置
        RegistryConfig registryConfig = new RegistryConfig();
        // 注册中心这里需要配置上注册中心协议,例如下面的zookeeper
        registryConfig.setAddress("zookeeper://192.168.0.1:2181");
        registryConfig.setGroup("test_group");
        reference.setApplication(applicationConfig);
        reference.setRegistry(registryConfig);
        // 设置调用的reference属性,下面只设置了协议、接口名、版本、超时时间
        reference.setProtocol("dubbo");
        reference.setInterface("com.xxx.test.TestService");
        reference.setVersion("1.0.0");
        reference.setTimeout(1000);
        // 声明为泛化接口
        reference.setGeneric(true);
        // GenericService可以接住所有的实现
        GenericService genericService = reference.get();
        // 构造复杂参数,下面的示例中,头两个参数为string类型,后一个是一个复杂类型,但都可以通过map构造。
        Map<String, Object> param = new HashMap<>();
        param.put("test1", "a");
        param.put("test2", "b");
        Map<String,Object> thirdParam = new HashMap<>();
        thirdParam.put("class","java.util.Map");
        thirdParam.put("subParam1","c");
        thirdParam.put("subParam2","d");
        param.put("test3",thirdParam);
        Object result = genericService.$invoke("myMethod", new String[]{"java.lang.String", "java.lang.String", "com.xxxtest.MyParam"}, new Object[]{"123", "ddd",param});
        System.out.println(JSON.toJSONString(result));
    }
}

作者:气球到处飞
链接:https://www.jianshu.com/p/3a22a53c7068

相关文章

  • dubbo泛化调用

    为什么要使用泛化调用? 一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服...

  • dubbo泛化调用

    为什么要使用泛化调用? 一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服...

  • Dubbo泛化调用

    泛化调用示例: 原理:泛化调用本质是在filter过滤链上执行的序列化和反序列化操作消费者端对应的过滤器是Gene...

  • dubbo泛化调用指南

    在如今的各种大型分布式系统中,dubbo框架已成为一颗明星。而作为内部rpc,它无法承担对外输出的功能,此...

  • Dubbo-泛化调用-泛型

    背景 今天刚好有需求需要用到dubbo的泛化调用,涉及到了泛型问题:服务端无法获取泛型对象的数据,特此记录。 解决...

  • 十四、soul源码学习-dubbo请求泛化调用

    这一节我们来讲一下dubbo请求的泛化调用。 dubbo请求到网关后,会进入到ApacheDubboPlugin中...

  • dubbo泛化调用性能优化

    https://sq.163yun.com/blog/article/185512233177817088[htt...

  • Dubbo 泛化引用和泛化实现

    开篇  在Dubbo官方文档中关于泛化调用和泛化实现的说明,这里针对文档的案例做一些简单的说明和解释。 例子 例子...

  • 记一次Dubbo的异常处理

    Dubbo的异常处理 最近项目中在使用到泛化的网关处理。这里分享一下,在调用的过程中,Dubbo对异常的处理。 官...

  • Dubbo 泛化调用在vivo统一配置系统的应用

    作者:vivo 互联网服务器团队- Wang Fei、LinYupan Dubbo泛化调用特性可以在不依赖服务接口...

网友评论

      本文标题:dubbo泛化调用

      本文链接:https://www.haomeiwen.com/subject/xuprtltx.html