2) 通过API使用泛化调用
服务启动方
• 在设置ServiceConfig时,使用setGeneric("true")来开启泛化调用。
• 在设置ServiceConfig时,使用setRef指定实现类时,要设置一个GenericService的对象。而不是真正的服务实现类对象。
• 其他设置与正常Api服务启动一致即可。
//定义泛化调用服务类 private static GenericService genericService; public static void main(String[] args) throws Exception { //创建ApplicationConfig ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("generic-call-consumer"); //创建注册中心配置 RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("zookeeper://127.0.0.1:2181"); //创建服务引用配置 ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>(); //设置接口 referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService"); applicationConfig.setRegistry(registryConfig); referenceConfig.setApplication(applicationConfig); //重点:设置为泛化调用 //注:不再推荐使用参数为布尔值的setGeneric函数 //应该使用referenceConfig.setGeneric("true")代替 referenceConfig.setGeneric(true); //设置异步,不必须,根据业务而定。 referenceConfig.setAsync(true); //设置超时时间 referenceConfig.setTimeout(7000); //获取服务,由于是泛化调用,所以获取的一定是GenericService类型 genericService = referenceConfig.get(); //使用GenericService类对象的$invoke方法可以代替原方法使用 //第一个参数是需要调用的方法名 //第二个参数是需要调用的方法的参数类型数组,为String数组,里面存入参数的全类名。 //第三个参数是需要调用的方法的参数数组,为Object数组,里面存入需要的参数。 Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"}); //使用CountDownLatch,如果使用同步调用则不需要这么做。 CountDownLatch latch = new CountDownLatch(1); //获取结果 CompletableFuture<String> future = RpcContext.getContext().getCompletableFuture(); future.whenComplete((value, t) -> { System.err.println("invokeSayHello(whenComplete): " + value); latch.countDown(); }); //打印结果 System.err.println("invokeSayHello(return): " + result); latch.await(); }
3) 通过Spring使用泛化调用
Spring中服务暴露与服务发现有多种使用方式,如xml,注解。这里以xml为例。
步骤:
• 生产者端无需改动。
• 消费者端原有的dubbo:reference标签加上generic=true的属性。
• 获取到Bean容器,通过Bean容器拿到GenericService实例。
• 调用$invoke方法获取结果。