dubbo泛化调用

发布时间 2023-11-30 23:09:07作者: 使用D

java调用其他api时,一般都是需要引用对应的jar包,在使用对应的出入参Class进行调用api接口,还是通过泛化方式即接口全路径、接口名称、入参为Map、出参为Map  通过这种方式可以屏蔽远程依赖。

 泛化调用核心接口

根据传入的接口方法、入参类型字符串数组、入参值字符数组、

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 GenericException potential exception thrown from the invocation
     */
    Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

    default CompletableFuture<Object> $invokeAsync(String method, String[] parameterTypes, Object[] args)
            throws GenericException {
        Object object = $invoke(method, parameterTypes, args);
        if (object instanceof CompletableFuture) {
            return (CompletableFuture<Object>) object;
        }
        return CompletableFuture.completedFuture(object);
    }
}

一种方式是实现GenericService接口

public class GenericImplOfHelloService implements GenericService {
    @Override
    public Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException {
        if (method.equals("sayHello")) {
            System.out.print("executing sayHello.");
            throw new RuntimeException("sayHello: throws exception");
        } else if (method.equals("sayHelloAsync")) {
            System.out.print("executing sayHelloAsync.");
            return CompletableFuture.completedFuture("sayHelloAsync: hello " + args[0]);
        } else {
            try {
                return defaultOperation(method, parameterTypes, args);
            } catch (Exception e) {
                throw new GenericException(e);
            }
        }
    }

    private Object defaultOperation(String method, String[] parameterTypes, Object[] args) throws Exception {
        throw new UnsupportedOperationException("method does not exist.");
    }
}

具体调用方式

ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
//指定api接口
referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
applicationConfig.setRegistry(registryConfig);
referenceConfig.setApplication(applicationConfig);
referenceConfig.setGeneric("true");
referenceConfig.setAsync(true);
referenceConfig.setTimeout(7000);
genericService = referenceConfig.get();
//调用对应接口的方法、入参类型、入参值
Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});

provider实际上注册到了zk中的形式是一个url

dubbo://192.168.239.1:20880/org.apache.dubbo.samples.generic.call.api.HelloService?application=generic-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.samples.generic.call.api.HelloService&methods=sayHello,sayHelloAsync,sayHelloAsyncComplex,sayHelloAsyncGenericComplex&prefer.serialization=fastjson2,hessian2&release=3.2.6&service-name-mapping=true&side=provider&timestamp=1701356673623&token=141fb589-c2b7-447d-9e48-4da2eaf06c90