专栏首页赵KK日常技术记录他们总说Dubbo泛化是啥啊?

他们总说Dubbo泛化是啥啊?

前几天听同事讨论问题,偶然间冒出来一句,那用Dubbo泛化解决,我就惊奇了一下,要在实际场景用到泛化了吗?我在有道云笔记的2020.3.31篇中首次记录了泛化的出现。

泛化是啥?

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

我跑去问组长,他们那天说的泛化是啥?我们什么场景要用啊?

泛化就是你不知道你不关心下层实现,只需要约定接口及参数,实现由下层实现,但是这样一来扩展性和可用性极低,不如你约定一个接口,提供方注册到ZK上,消费方去ZK去拉,或者干脆提供个jar包,然后通过普通的注册去调用就可以。

至于场景是因为临时接入的第三方数据服务,不能直接调用,我们中间提供了接口,实现是他们实现的。

关键字:generic

通过 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[]

通过 API 方式使用泛化调用

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

// 用org.apache.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});
 
...

泛化的实现

通过 API 方式暴露泛化实现

...
// 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口实现
GenericService xxxService = new XxxGenericService();

// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
// 弱类型接口名
service.setInterface("com.xxx.XxxService");
service.setVersion("1.0.0");
// 指向一个通用服务实现
service.setRef(xxxService);
 
// 暴露及注册服务
service.export();

注册到ZK实现

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://127.0.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));
    }

仅是了解到泛化的基础概念,适用场景不多,结合官网及资料,需要实际项目了解下实际实现。

本文分享自微信公众号 - 赵KK日常技术记录(gh_cc4c9f1a9521),作者:赵kk

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 开源项目Springboot_v2真香系列

    之前找过很多开源项目,用于生成代码,和权限管理,但功能全的需要付费,小功能的项目又不实用,这次的开源项目,功能十分强大,且拿来即用。

    疯狂的KK
  • Shiro认证过程

    Shiro的架构了解之后,走一下debug,跟一下认证的流程。使用Realm来认证用户名密码。

    疯狂的KK
  • 我转载了CSDN一篇5万+访问量的文章

    逆向生成实体类等文件,是项目常用技能,单纯IDEA插件也可以实现将数据库表字段直接生成到指定文件夹下的实体类,Mybatis的逆向工程还可生成C...

    疯狂的KK
  • java实现多个网络文件批量下载并压缩

    文档管理模块,列表中显示的记录的每日文件上传保存的记录.每条数据中有一个字段存放了文件的存储地址文件服务器上

    java攻城狮
  • STSGCN:时空同步图卷积神经网络用于交通预测

    《Spatial-Temporal Synchronous Graph Convolutional Networks: A New Framework for ...

    深度学习与交通大数据
  • IO 流最全讲解

    流 : 流动 、流向 从一端移动到另一端(源头与目的地) 程序 与 文件|数组|网络连接|数据库,以程序为中心

    帅飞
  • Kotlin入门(10)七十二变的输入参数

    上一篇文章介绍了Kotlin对函数的基本用法,包括函数的定义、输入参数的声明、输出参数的声明等等,这些足够对付简单的场合了。当...

    用户4464237
  • 整合ThinkPHP功能系列之微信公众号模板消息发送

    所有服务号都可以在功能、添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限

    沈唁
  • android仿微信好友列表功能

    android studio实现微信好友列表功能,注意有一个jar包我没有放上来,请大家到MainActivity中的那个网址里面下载即可,然后把pinyin4...

    砸漏
  • docker--docker 网络管理

    Docker中默认的三种网络分别为bridge、host和none,其中名为bridge的网络就是默认 的bridge驱动网络,也是容器创建时默认的网络管理方式...

    eadela

扫码关注云+社区

领取腾讯云代金券