Dubbo泛化调用

什么是泛化调用?
泛化调用就是服务消费者端因为某种原因并没有该服务接口,这个原因有很多,比如是跨语言的,一个PHP工程师想调用某个java接口,他并不能按照你约定,去写一个个的接口,Dubbo并不是跨语言的RPC框架,但并不是不能解决这个问题,这个PHP程序员搭建了一个简单的java web项目,引入了dubbo的jar包,使用dubbo的泛化调用,然后利用web返回json,这样也能完成跨语言的调用。泛化调用的好处之一就是这个了。
简而言之,泛化调用,最最直接的表现就是服务消费者不需要有任何接口的实现,就能完成服务的调用。
 
为什么要使用泛化调用?
一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服务使用的接口定义和方法定义(还有入参返参类型等等信息,常常还需要基于provider端提供的API),两端才能正常通信调用。
然而存在一种使用场景,调用方并不关心要调用的接口的详细定义,它只关注我要调用哪个方法,需要传什么参数,我能接收到什么返回结果即可,这样可以大大降低consumer端和provider端的耦合性。
所以为了应对以上的需求,dubbo提供了泛化调用,也就是在consumer只知道一个接口全限定名以及入参和返参的情况下,就可以调用provider端的调用,而不需要传统的接口定义这些繁杂的结构。
 
 
泛化调用使用的是GenericService接口
 
一、示例
(1)服务提供者
public interface TestService {
    List<String> getListById(Long id);
}

public class TestServiceImpl implements TestService {

    @Override
    public List<String> getListById(Long id) {
        List<String> list = new ArrayList<String>();
        list.add("test1-" + id);
        list.add("test2-" + id);
        list.add("test3-" + id);
        return list;
    }
}
<dubbo:service retries="0" interface="com.generic.TestService" ref="testService"/>
服务提供者没有任何变化
 
 
(2)服务消费者
需要配置一个generic="true"
<dubbo:reference id="testService" interface="com.generic.TestService" generic="true"/>  
public static void main(String[] args) {
    ClassPathXmlApplicationContext context = 
        new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
    GenericService testService = (GenericService) context.getBean("testService");
    Object result = testService.$invoke("getListById", new String[] { "java.lang.Long" }, new Object[]{ "666" });
    System.out.println(result);
}
 
二、不依赖spring配置文件
我们刚才说,一个PHP程序员想要搭建一个简单的web项目,可是你却叫他依赖于spring的配置文件,对他难度是不小的,dubbo也帮你想到了,泛型调用,服务消费端可以不依赖spring的配置文件,我们重新写下测试类Consumer
public static void main(String[] args) {

    // 普通编码配置方式  
    ApplicationConfig application = new ApplicationConfig();  
    application.setName("dubbo-consumer");  

    // 连接注册中心配置  
    RegistryConfig registry = new RegistryConfig();  
    registry.setAddress("zookeeper://127.0.0.1:2181");  

    ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();  
    reference.setApplication(application);  
    reference.setRegistry(registry);  
    reference.setInterface("com.generic.TestService");  
    reference.setGeneric(true); // 声明为泛化接口  

    ReferenceConfigCache cache = ReferenceConfigCache.getCache();  
    GenericService genericService = cache.get(reference);  

    // 基本类型以及Date,List,Map等不需要转换,直接调用  
    Object result = genericService.$invoke("getListById", new String[] { "java.lang.Long" },  
                                           new Object[] { 1L });  
    System.out.println(result);
}
泛化调用可以方便用户对dubbo服务消费者端的扩展,可以方便,丰富了服务消费者的调用方式,甚至可以做变相的Rest调用,这些都是可以的,不过,它的缺点也是很明显的,参数传递复杂,不方便使用。但是这种方式是不能缺失的
 
原文地址:https://www.cnblogs.com/caoxb/p/13140404.html