使用泛化调用

实现一个通用的服务测试框架,可通过 GenericService 调用所有服务实现

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

通过 Spring 使用泛化调用

在 Spring 配置申明 generic="true"

  1. <dubbo:reference id="barService" interface="com.foo.BarService" generic="true" />

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

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

通过 API 方式使用泛化调用

  1. import org.apache.dubbo.rpc.service.GenericService;
  2. ...
  3. // 引用远程服务
  4. // 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
  5. ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
  6. // 弱类型接口名
  7. reference.setInterface("com.xxx.XxxService");
  8. reference.setVersion("1.0.0");
  9. // 声明为泛化接口
  10. reference.setGeneric(true);
  11. // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
  12. GenericService genericService = reference.get();
  13. // 基本类型以及Date,List,Map等不需要转换,直接调用
  14. Object result = genericService.$invoke("sayHello", new String[] {"java.lang.String"}, new Object[] {"world"});
  15. // 用Map表示POJO参数,如果返回值为POJO也将自动转成Map
  16. Map<String, Object> person = new HashMap<String, Object>();
  17. person.put("name", "xxx");
  18. person.put("password", "yyy");
  19. // 如果返回POJO将自动转成Map
  20. Object result = genericService.$invoke("findPerson", new String[]
  21. {"com.xxx.Person"}, new Object[]{person});
  22. ...

有关泛化类型的进一步解释

假设存在 POJO 如:

  1. package com.xxx;
  2. public class PersonImpl implements Person {
  3. private String name;
  4. private String password;
  5. public String getName() {
  6. return name;
  7. }
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. public String getPassword() {
  12. return password;
  13. }
  14. public void setPassword(String password) {
  15. this.password = password;
  16. }
  17. }

则 POJO 数据:

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

可用下面 Map 表示:

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

最后修改 September 21, 2021: Bug fix miss mialbox (#953) (57cf51b)