泛化调用

客户端在不需要依赖服务端的接口情况下就能够发起调用。

  1. ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
  2. .setInterfaceId("com.alipay.sofa.rpc.quickstart.HelloService")
  3. .setGeneric(true);
  4. GenericService testService = consumerConfig.refer();
  5. String result = (String) testService.$invoke("sayHello", new String[] { "java.lang.String" },new Object[] { "1111" });

如上通过 setGeneric 设置该服务为泛化服务,设置服务方的接口名。以 GenericService 作为泛化服务,通过 GenericService 就能够发起泛化调用了。发起调用时,需要传入方法名,方法类型,方法参数。

如果参数或者返回结果在客户端也需要泛化表示。可以通过 GenericObject 来实现。

  1. GenericObject genericObject = new GenericObject("com.alipay.sofa.rpc.invoke.generic.TestObj");
  2. genericObject.putField("str", "xxxx");
  3. genericObject.putField("num", 222);
  4. GenericObject result = (GenericObject) testService.$genericInvoke("echoObj",
  5. new String[] { "com.alipay.sofa.rpc.invoke.generic.TestObj" },
  6. new Object[] { genericObject });
  7. String str = result.getField("str");
  8. String num = result.getField("num");

如上就能获得序列化结果。完整的泛化调用方式使用说明如下:

  1. /**
  2. * Java Bean
  3. */
  4. public class People {
  5. private String name;
  6. private int age;
  7. // getters and setters
  8. }
  9. /**
  10. * 服务方提供的接口
  11. */
  12. interface SampleService {
  13. String hello(String arg);
  14. People hello(People people);
  15. String[] hello(String[] args);
  16. }
  17. /**
  18. * 客户端
  19. */
  20. public class ConsumerClass {
  21. GenericService genericService;
  22. public void do() {
  23. // 1. $invoke仅支持方法参数类型在当前应用的 ClassLoader 中存在的情况
  24. genericService.$invoke("hello", new String[]{ String.class.getName() }, "I'm an arg");
  25. // 2. $genericInvoke支持方法参数类型在当前应用的 ClassLoader 中不存在的情况。
  26. // 2.1 构造参数
  27. GenericObject genericObject = new GenericObject("com.alipay.sofa.rpc.test.generic.bean.People"); // 构造函数中指定全路径类名
  28. genericObject.putField("name", "Lilei"); // 调用putField,指定field值
  29. genericObject.putField("age", 15);
  30. // 2.2 进行调用,不指定返回类型,返回结果类型为GenericObject
  31. Object obj = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject });
  32. Assert.assertTrue(obj.getClass == GenericObject.class);
  33. // 2.3 进行调用,指定返回类型
  34. People people = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject }, People.class);
  35. // 2.4 进行调用,参数类型是数组类型
  36. String[] result = (String[]) proxy.$genericInvoke("hello", new String[]{new String[0].getClass().getName()}, new Object[]{ new String[]{"args"} });
  37. }
  38. }