泛化调用

作者: w_yong | 来源:发表于2021-04-22 23:26 被阅读0次

什么是泛化调用

通常我们想调用别人的服务时,我们需要在项目中引入对应的jar包。而泛化调用的作用是,我们无需依赖相关jar包,也能调用到该服务。

这个特性一般使用在网关类项目中,在业务开发中基本不会使用。

使用方式

假设我现在要调用下面的接口服务

package com.scj.demo.dubbo.provider.service.impl;

public interface ByeService {

    String bye(String name);

}

api

ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setApplication(new ApplicationConfig("test"));
referenceConfig.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
referenceConfig.setInterface("com.scj.demo.dubbo.provider.service.impl.ByeService");
referenceConfig.setGeneric(true);
GenericService genericService = referenceConfig.get();

Object result = genericService.$invoke(
    "bye",
    new String[]{"java.lang.String"},
    new Object[]{"1234"});

System.out.println(result);

spring

在xml文件做以下配置

<dubbo:reference id="byeService" interface="com.scj.demo.dubbo.provider.service.impl.ByeService" generic="true" />

然后注入使用

@Service
public class PersonService {

    @Resource(name = "byeService")
    private GenericService genericService;

    public void sayBye(){
        Object result = genericService.$invoke(
                "bye",
                new String[]{"java.lang.String"},
                new Object[]{"1234"});
        System.out.println(result);
    }

}

在两种调用方式中,我们都需要使用被调用接口的字符串参数生成GenericService,通过GenericService的$invoke间接调用目标接口的接口。

public interface GenericService {

    /**
     * Generic invocation
     *
     * @param method         Method name, e.g. findPerson. If there are overridden methods, parameter info is
     *                       required, e.g. findPerson(java.lang.String)
     * @param parameterTypes Parameter types
     * @param args           Arguments
     * @return invocation return value
     * @throws Throwable potential exception thrown from the invocation
     */
    Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}

$invoke的三个参数分别为,方法名,方法参数类型数组,方法参数数组。

方法入参构造

可以看到泛化调用的一个复杂性在于$invoke的第三个参数的组装,下面介绍几种复杂入参的调用方式

首先丰富提供者接口

public interface ByeService {

    String bye(String name);

    String bye(String name, Long age, Date date);

    String bye(Person person);

    String bye(List<String> names);

    String bye(String[] names);

    String byePersons(List<Person> persons);

    String byePersons(Person[] persons);

    @Data
    public static class Person{
        private String name;

        private Long age;

        private Date birth;
    }

    public static void main(String[] args) {
        System.out.println(Person.class.getName());
    }

}

多参数

    @Test
    public void testMultiParam(){
        result = genericService.$invoke(
                "bye",
                new String[]{"java.lang.String","java.lang.Long","java.util.Date"},
                new Object[]{"scj",12L,new Date()});

        System.out.println(result);
    }

自定义对象

    Map<String,Object> personMap = new HashMap<>();
    {
        personMap.put("name","scj");
        personMap.put("age","12");
        personMap.put("birth",new Date());
    }

    @Test
    public void testPOJO(){

        result = genericService.$invoke(
                "bye",
                new String[]{"com.scj.demo.dubbo.provider.service.impl.ByeService$Person"},
                new Object[]{personMap});

        System.out.println(result);
    }

Map

    @Test
    public void testMap(){
        result = genericService.$invoke(
                "bye",
                new String[]{"java.util.Map"},
                new Object[]{personMap});

        System.out.println(result);
    }

集合

    @Test
    public void testList(){
        List<String> names = Lists.newArrayList("scj1","scj2");
        result = genericService.$invoke(
                "bye",
                new String[]{"java.util.List"},
                new Object[]{names});

        System.out.println(result);
    }

数组

    @Test
    public void testArray(){
        String[] nameArray = new String[]{"scj1","scj3"};
        result = genericService.$invoke(
                "bye",
                new String[]{"java.lang.String[]"},
                new Object[]{nameArray});

        System.out.println(result);
    }

集合+自定义对象

    @Test
    public void testPOJOList(){
        result = genericService.$invoke(
                "byePersons",
                new String[]{"java.util.List"},
                new Object[]{Lists.newArrayList(personMap,personMap)});

        System.out.println(result);
    }

数组+自定义对象

    @Test
    public void testPOJOArray(){
        result = genericService.$invoke(
                "byePersons",
                new String[]{"com.scj.demo.dubbo.provider.service.impl.ByeService$Person[]"},
                new Object[]{Lists.newArrayList(personMap,personMap)});

        System.out.println(result);
    }

结果返回

与入参相似,虽然$invoke的返回定义为Object,实际上针对不同类型有不同的返回。

相关文章

  • 泛化调用

    什么是泛化调用 通常我们想调用别人的服务时,我们需要在项目中引入对应的jar包。而泛化调用的作用是,我们无需依赖相...

  • 24.Dubbo泛化调用实现

    泛化调用的核心实现类GenericImplFilter, 消费端:GenericImplFilter将泛化参数进行...

  • dubbo泛化调用

    为什么要使用泛化调用? 一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服...

  • dubbo泛化调用

    为什么要使用泛化调用? 一般使用dubbo,provider端需要暴露出接口和方法,consumer端要十分明确服...

  • Dubbo泛化调用

    泛化调用示例: 原理:泛化调用本质是在filter过滤链上执行的序列化和反序列化操作消费者端对应的过滤器是Gene...

  • java 泛型

    1,如何实例化泛型 2,如何获取java中的泛型类型 调用(通常在构造方法中调用):

  • Dubbo-泛化调用-泛型

    背景 今天刚好有需求需要用到dubbo的泛化调用,涉及到了泛型问题:服务端无法获取泛型对象的数据,特此记录。 解决...

  • 泛型

    泛型概述 1:什么是泛型?: 泛型:“参数化类型”,可以从字面理解,参数化,在我们用参数中,定义方法用形参,调用传...

  • dubbo泛化调用指南

    在如今的各种大型分布式系统中,dubbo框架已成为一颗明星。而作为内部rpc,它无法承担对外输出的功能,此...

  • 7.泛化调用

    1.场景 当A项目没有拿到B项目的接口时,还想用rpc方式调用时 2.操练 客户端中:设置generic="tru...

网友评论

    本文标题:泛化调用

    本文链接:https://www.haomeiwen.com/subject/rrtkrltx.html