zoukankan      html  css  js  c++  java
  • dubbo里面的GenericService干啥的

    两个用途一直是泛化服务,一种是泛化引用。前者是为了provider省事,后者是消费者省事。先介绍泛化服务怎么做到的:

    比如提供者想省事,虽然提供了10个方法,但是不想在接口里面写十个方法,也就不用给这十个方法做函数声明、参数声明了。直接通过:

    ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
            service.setApplication(new ApplicationConfig("generic-provider"));
            service.setRegistry(new RegistryConfig("N/A"));
            service.setProtocol(new ProtocolConfig("dubbo", 29581));
            service.setInterface(DemoService.class.getName());
            service.setRef(new GenericService() {
    
                public Object $invoke(String method, String[] parameterTypes, Object[] args)
                        throws GenericException {
                    if ("sayName".equals(method)) {
                        return "Generic " + args[0];
                    }
                    if ("throwDemoException".equals(method)) {
                        throw new GenericException(DemoException.class.getName(), "Generic");
                    }
                    if ("getUsers".equals(method)) {
                        return args[0];
                    }
                    return null;
                }
            });
            service.export();
    

      也就是通过method不同,直接返回不同处理结果,隐藏了方法和参数声明。上面虽然 service.setInterface(DemoService.class.getName()),这里传入的是接口的str名称。也就是说通过generic,provider已经完全不依赖interface了,只是用到这个接口的名称字符串用做servericekey用的。

    之所以能这样操作,消费者在调用的时候,需要在url里面指定generic=true,那么在经过filter链的时候,在GenericImplFilter会做generic处理

    把method-name设置成$invoke

    parameter-types由于提供者不一定有,于是传入类型的string类型。

    args按照pojo或者java-bean进行序列化成一个map,里面指定了参数的class类型、每个filed的value。

    provider不会把这个map做逆序列化处理,直接原样返回这个map,所以可以看到这个generic的provider能够处理的东西比较有限。消费者在得到结果的时候,依然是一个map,那么在GenericImplFilter里面,把invoke得到的结果逆序列化成具体的对象。也就是说由GenericImplFilter序列化成一个map,你自己负责逆序列化。

    对于泛化引用的话,例子如下:

    ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
                reference.setApplication(new ApplicationConfig("generic-consumer"));
                reference.setInterface(DemoService.class);
                reference.setUrl("dubbo://127.0.0.1:29581?scope=remote");
                reference.setGeneric(true);
                GenericService genericService = reference.get();
                try {
                    List<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
                    Map<String, Object> user = new HashMap<String, Object>();
                    user.put("class", "com.alibaba.dubbo.config.api.User");
                    user.put("name", "actual.provider");
                    users.add(user);
                    users = (List<Map<String, Object>>) genericService.$invoke("getUsers", new String[]{List.class.getName()}, new Object[]{users});
                    
    

      

    消费者直接使用$invoke方法,不用考虑provider到底提供了哪些方法,通过字符串getuser调用,参数类型也不用关心,直接用map描述参数的类型和value。

    provider在被调用的时候,还是GenericImplFilter这个filter里面,由provider通过map进行逆序列化,毕竟provider提供的方法里面是按照这个参数类型进行处理的,所以必须从map转化成真正的类型,处理完成以后,还要逆序列化成map才能返回给consumer,因为consumer只认识map,不认识具体参数类型。

  • 相关阅读:
    tty初探 — uart驱动框架分析
    是否要从单片机转为嵌入式Linux?
    Linux 下Input系统应用编程实战
    Linux设备驱动之Kobject、Kset
    Xorg-xserver相关知识
    linux各级目录
    GitHub使用基本流程
    6、Linux发行版组成与初识
    CentOS7安装出现Warning
    Python数据类型之变量
  • 原文地址:https://www.cnblogs.com/notlate/p/10127942.html
Copyright © 2011-2022 走看看