Dubbo的GenericService简介和基本使用

63 篇文章 11 订阅

 

简介

GenericService是Dubbo提供的泛化接口,用来进行泛化调用。

GenericService接口只有一个方法:

Object $invoke(String var1, String[] var2, Object[] var3) throws GenericException;

第一个参数是方法名。

第二个参数是一个字符串数组,这是接口方法每个参数类型的全路径。

第三个参数是Object数组,是传给方法的具体参数列表。

Dubbo服务的提供者和消费者都可以使用这个接口,场景略有不同,二者也未必同时存在,可以由提供者使用GenericService,消费者用具体接口类,或者消费者使用GenericService,提供者用具体接口类,或者提供者和消费者都用GenericService,只要指定的接口能对得上,调用都没问题。

下面分别看一下。

 

服务提供者使用GenericService

当服务提供者使用这个接口时,可以省略Interface的代码,省略方法和参数的声明,通过指定接口名称的方式向zookeeper发布Dubbo服务。

这时GenericService就像是一个网关。

举个例子:

@Override
public void afterSingletonsInstantiated() {
    ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
    ApplicationConfig application = new ApplicationConfig("test-provider");
    service.setApplication(application);
    RegistryConfig registryConfig = new RegistryConfig();
    registryConfig.setAddress("zookeeper://127.0.0.1:2181");
    service.setRegistry(registryConfig);
    service.setInterface("com.suibian.WhateverService");

    GenericService genericService = (method, parameterTypes, args) -> {
        if ("method1".equals(method)) {
            return "method1 result:" + args[0];
        }
        if ("method2".equals(method)) {
            return 12345;
        }
        if (parameterTypes.length == 2
                && parameterTypes[0].equals("java.lang.String")
                && parameterTypes[1].equals("java.lang.Integer")
                && "method3".equals(method)) {
            return "method3,param1:" + args[0] + ",param2:" + args[1];
        }
        return null;
    };
    service.setRef(genericService);
    service.export();
}

大概说明一下:

1,registryConfig里需要写好注册中心地址。zookeeper注册中心格式是这样的:zookeeper://127.0.0.1:2181

2,ServiceConfig.setInterface()用于指定要发布的接口名称,这个名称可以不对应任何的java接口类,甚至可以随便写。在上面的例子中com.suibian.WhateverService这个名字就是随便写的,实际上代码中并没有这个接口类。

3,因为这样发布的Dubbo服务没有具体的接口类,所以invoke()方法的第一个参数String var1(原本是方法名)和第二个参数String[] var2(原本是方法参数类型列表)就脱离了具体接口类的束缚,可以接收任意值,就像上面例子中所写的一样,按照不同的参数执行不同的逻辑,就像一个网关一样。

4,Dubbo服务的发布本身不需要Spring服务启动,但如果把上面的代码放在main()方法中,随着进程结束,发布的Dubbo服务也会立即被取消。

5,向zookeeper中注册好的GenericService在zookeeper中是这样的:

[zk: localhost:2181(CONNECTED) 4] ls /dubbo/com.suibian.WhateverService/providers

[dubbo%3A%2F%2F172.16.111.111%3A20880%2Fcom.suibian.WhateverService%3Fanyhost%3Dtrue%26application%3Dtest-provider%26dubbo%3D2.5.3%26generic%3Dtrue%26interface%3Dcom.suibian.WhateverService%26methods%3D*%26pid%3D3856%26side%3Dprovider%26timestamp%3D1592905521950]

可以看到里面没有方法列表,有generic标识。

 

服务消费者使用GenericService

当服务消费者使用这个接口时,有个好处是不依赖服务提供者的Interface接口类,而是通过指定具体接口类路径的方式,创建消费者,并去zookeeper查找对应的提供者,然后发起调用。

举个例子:

public static void test3() {

    ApplicationConfig application = new ApplicationConfig("test-consumer"); //参数为dubbo消费方的名称
    RegistryConfig registryConfig = new RegistryConfig();
    registryConfig.setAddress("zookeeper://127.0.0.1:2181");
    application.setRegistry(registryConfig);

    ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
    reference.setApplication(application);
    reference.setInterface("com.suibian.WhateverService");
    reference.setTimeout(3000);
    reference.setGeneric(true);
    GenericService genericService = reference.get();
    Object object1 = genericService.$invoke("method1", new String[]{"java.lang.String"}, new Object[]{"this is parameter"});    //调用泛化接口
    System.out.println(object1);

    Object object2 = genericService.$invoke("method2", new String[]{"java.lang.String"}, new Object[]{"this is parameter"});    //调用泛化接口
    System.out.println(object2);

    Object object3 = genericService.$invoke("method3", new String[]{"java.lang.String", "java.lang.Integer"}, new Object[]{"ABCD", 1234});    //调用泛化接口
    System.out.println(object3);

}

public static void main(String[] args) {
    test3();
}

根据上面提供者发布的接口,这次调用输出的结果是:

method1 result:this is parameter
12345
method3,param1:ABCD,param2:1234

可以看到,消费者使用GenericService时并不需要启动Spring服务,reference.get()方法会直接向zookeeper注册consumer,然后调用invoke()方法发起调用。

使用时记得加上reference.setGeneric(true);

 

invoke()方法的返回值类型

因为不依赖提供者的接口类,只是指定了接口类名和参数,所以调用时无法知道方法具体的返回值类型。

虽然invoke()方法的返回类型统一都是Object,不过还是能分成以下几种情况:

1,方法的返回类型是简单类型,比如Integer和String,比如这样的方法:

Integer findOne (String code);

返回的类型就是这种简单类型本身。

2,方法的返回类型是单个非简单元素,比如这样的方法:

Student findOne (String code);

返回值类型实际上是HashMap。key是提供者的接口类中方法返回类型的属性名,value是属性值。

3,方法的返回类型是列表,比如这样的方法:

List<Student> findList (String code);

返回值类型实际上是ArrayList<HashMap>。

 

本文结束

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dubbo是一种高性能的Java RPC框架,用于构建分布式服务架构。它提供了服务注册与发现、负载均衡、容错、动态代理等功能,可以帮助开发者轻松构建可扩展的分布式系统。 Zookeeper是一个开源的分布式协调服务框架,它提供了高可用性、高性能和可靠性的分布式协调功能。在Dubbo中,Zookeeper通常用于服务注册与发现。它为分布式系统提供了一个一致性的命名空间,并提供了强大的监控和通知机制,使得服务能够动态地注册和发现。 具体使用Dubbo和Zookeeper的步骤如下: 1. 配置Zookeeper:首先需要安装和配置Zookeeper服务器,并确保其正常运行。 2. 引入Dubbo依赖:在项目的构建配置文件中,引入Dubbo相关的依赖。 3. 配置Dubbo:在应用程序的配置文件中,配置Dubbo相关的参数,如注册中心地址、端口等。 4. 编写服务接口:定义需要暴露的服务接口。 5. 编写服务实现:实现服务接口,并使用Dubbo的注解来标识服务的相关信息。 6. 启动Dubbo服务:在应用程序中启动Dubbo服务提供者,将服务注册到Zookeeper上。 7. 调用Dubbo服务:在应用程序中使用Dubbo的引用注解来引用需要调用的服务。 8. 配置消费者:在消费者端的配置文件中,配置消费者相关的参数,如注册中心地址、端口等。 9. 启动消费者:在应用程序中启动Dubbo服务消费者,通过Dubbo的引用注解来调用远程服务。 通过以上步骤,你可以使用Dubbo和Zookeeper搭建起一个分布式服务架构,并实现服务的注册、发现和调用。希望对你有所帮助!如有更多问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值