返回
从头开始:在不依赖第三方 JAR 包的情况下优雅地进行 Dubbo 调用
后端
2023-09-15 08:31:47
在不引入第三方 JAR 包的情况下优雅地进行 Dubbo 调用
作为开发人员,我们经常需要与外部服务进行通信。Dubbo 是一个流行的分布式服务框架,允许我们轻松地进行远程过程调用 (RPC)。然而,在某些情况下,我们可能希望在不引入第三方 JAR 包的情况下使用 Dubbo 服务。
本文将介绍一种优雅的方法,让你能够在不依赖第三方 JAR 包的情况下进行 Dubbo 调用。这对于希望保持应用程序精简和独立的开发人员特别有用。
背景
默认情况下,Dubbo 客户端需要使用生产者提供的客户端 JAR 包才能进行调用。这可能会导致应用程序依赖关系过多,并且难以管理。为了解决这个问题,我们可以使用 Dubbo 的原生协议,它允许客户端直接与服务器进行通信,而无需客户端 JAR 包。
技术要求
- Java 8 或更高版本
- Dubbo 3.0 或更高版本
步骤
- 使用原生协议
首先,我们需要配置 Dubbo 客户端以使用原生协议。这可以通过在 dubbo.properties
文件中添加以下属性来实现:
dubbo.protocol.dubbo=dubbo://
- 确定服务全限定类名
要调用服务,我们需要知道其全限定类名。这可以通过查看生产者提供的接口或实现类来确定。
- 创建代理类
接下来,我们需要创建代理类来代表 Dubbo 服务。这可以通过使用 com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler
类来实现。
public class MyProxy implements InvocationHandler {
private String host;
private int port;
private String serviceInterfaceName;
public MyProxy(String host, int port, String serviceInterfaceName) {
this.host = host;
this.port = port;
this.serviceInterfaceName = serviceInterfaceName;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 构造 Dubbo URL
URL url = new URL("dubbo", host, port, serviceInterfaceName);
// 创建 Dubbo 消费者
Invoker<?> invoker = new JdkRpcInvoker(url);
// 执行 RPC 调用
return invoker.invoke(new Invocation(method, args));
}
}
- 创建服务代理
最后,我们需要使用代理类创建服务代理。这可以通过以下方式实现:
ProxyFactory proxyFactory = new ProxyFactory();
Object proxy = proxyFactory.getProxy(MyProxy.class);
示例代码
以下是一个完整的示例代码:
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DubboClientWithoutJar {
public static void main(String[] args) {
// 配置 Dubbo 原生协议
System.setProperty("dubbo.protocol.dubbo", "dubbo://");
// 服务地址
String host = "127.0.0.1";
int port = 20880;
// 服务接口全限定类名
String serviceInterfaceName = "com.example.demo.DemoService";
// 创建服务代理
Object proxy = createProxy(host, port, serviceInterfaceName);
// 调用服务方法
Method method = proxy.getClass().getMethod("sayHello", String.class);
Object result = method.invoke(proxy, "World");
// 打印结果
System.out.println(result);
}
private static Object createProxy(String host, int port, String serviceInterfaceName) {
// 创建代理类
MyProxy myProxy = new MyProxy(host, port, serviceInterfaceName);
// 创建服务代理
ProxyFactory proxyFactory = new ProxyFactory();
Object proxy = proxyFactory.getProxy(myProxy);
return proxy;
}
private static class MyProxy implements InvocationHandler {
private String host;
private int port;
private String serviceInterfaceName;
public MyProxy(String host, int port, String serviceInterfaceName) {
this.host = host;
this.port = port;
this.serviceInterfaceName = serviceInterfaceName;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 构造 Dubbo URL
URL url = new URL("dubbo", host, port, serviceInterfaceName);
// 创建 Dubbo 消费者
Invoker<?> invoker = new JdkRpcInvoker(url);
// 执行 RPC 调用
Invocation invocation = new RpcInvocation(method, args);
Result result = invoker.invoke(invocation);
// 返回结果
return result.getValue();
}
}
}
优势
使用这种方法具有以下优势:
- 应用程序精简: 不需要依赖第三方 JAR 包,从而保持应用程序精简。
- 独立性: 应用程序不再依赖于生产者提供的客户端 JAR 包,从而提高了独立性。
- 灵活性: 它允许我们在不修改生产者代码的情况下调用 Dubbo 服务。