一、简介
需求:Dubbo的调用方,在不引入服务接口类的情况下,远程调用其他Dubbo服务。
二、项目依赖
SpringBoot整合Dubbo3.x关于curator和zookeeper版本选型的思考
经尝试,
一种方案是使用高版本组合(Curator 5.2.0 + ZooKeeper 3.6.3);
另一种方案是选用低版本组合(Curator 4.2.0 + ZooKeeper 3.4.10)。
三、核心代码
参考自 Apache Dubbo 高级用法 使用泛化调用
如果引用的是 Dubbo 3.0.5
import cn.hutool.core.util.StrUtil; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.utils.SimpleReferenceCache; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.service.GenericService; import org.springframework.lang.Nullable; /** * 功能描述: 基于 Dubbo 泛化调用特性的远程调用 * * @author geekziyu * @version 1.0.0 */ class DubboRpc { private RegistryConfig registry; DubboRpc(ApplicationConfig application, RegistryConfig registry) { this.registry = registry; ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application); } Object genericInvoke(String interfaceClass, String methodName, String[] parameterTypes, Object[] args) { return genericInvoke(interfaceClass, methodName, parameterTypes, args, null, null); } Object genericInvoke(String interfaceClass, String methodName, String[] parameterTypes, Object[] args, @Nullable String group, @Nullable String version) { ReferenceConfig<GenericService> reference = new ReferenceConfig<>(); reference.setRegistry(registry); reference.setInterface(interfaceClass); // 接口名 reference.setGeneric("true"); // 声明为泛化接口 reference.setCheck(false); // 不检查状态 if (StrUtil.isNotBlank(group)) { // NOSONAR reference.setGroup(group); } if (StrUtil.isNotBlank(version)) {// NOSONAR reference.setVersion(version); } // ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接, // 需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。 // API方式编程时,容易忽略此问题。 // 这里使用dubbo内置的简单缓存工具类进行缓存 SimpleReferenceCache cache = SimpleReferenceCache.getCache(); GenericService genericService = cache.get(reference); // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用 return genericService.$invoke(methodName, parameterTypes, args); } }
如果引用的是 Dubbo 3.0.1
import cn.hutool.core.util.StrUtil; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.utils.ReferenceConfigCache; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.service.GenericService; import javax.annotation.Nullable; /** * 功能描述: 基于 Dubbo 泛化调用特性的远程调用 * * @author 20024968@cnsuning.com * @version 1.0.0 */ class DubboRpc { private RegistryConfig registry; DubboRpc(ApplicationConfig application, RegistryConfig registry) { this.registry = registry; ApplicationModel.getConfigManager().setApplication(application); } Object genericInvoke(String interfaceClass, String methodName, String[] parameterTypes, Object[] args) { return genericInvoke(interfaceClass, methodName, parameterTypes, args, null, null); } Object genericInvoke(String interfaceClass, String methodName, String[] parameterTypes, Object[] args, @Nullable String group, @Nullable String version) { referenceConfig<GenericService> reference = new ReferenceConfig<>(); reference.setRegistry(registry); reference.setInterface(interfaceClass); // 接口名 reference.setGeneric("true"); // 声明为泛化接口 reference.setCheck(false); // 不检查状态 if (StrUtil.isNotBlank(group)) { // NOSONAR reference.setGroup(group); } if (StrUtil.isNotBlank(version)) {// NOSONAR reference.setVersion(version); } // ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接, // 需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。 // API方式编程时,容易忽略此问题。 // 这里使用dubbo内置的简单缓存工具类进行缓存 ReferenceConfigCache cache = ReferenceConfigCache.getCache(); GenericService genericService = cache.get(reference); // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用 return genericService.$invoke(methodName, parameterTypes, args); } }
至于这个 RegistryConfig 可以这样:
@Service public class RpcInvokerService implements InitializingBean { @Value("${dubbo.application.name}") private String applicationName; @Value("${dubbo.registry.protocol}") private String protocol; @Value("${dubbo.registry.address}") private String address; private DubboRpc rpc; @Override public void afterPropertiesSet() { ApplicationConfig application = new ApplicationConfig(applicationName); RegistryConfig registry = new RegistryConfig(); registry.setProtocol(protocol); registry.setAddress(address); rpc = new DubboRpc(application, registry); } // ... }
发表评论