他们总说Dubbo泛化是啥啊?
【摘要】 前几天听同事讨论问题,偶然间冒出来一句,那用Dubbo泛化解决,我就惊奇了一下,要在实际场景用到泛化了吗?我在有道云笔记的2020.3.31篇中首次记录了泛化的出现。泛化是啥?官网解释:泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过 GenericService ...
前几天听同事讨论问题,偶然间冒出来一句,那用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));
}
仅是了解到泛化的基础概念,适用场景不多,结合官网及资料,需要实际项目了解下实际实现。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)