Java怎么优雅的调用dubbo同时不使用其它jar包
本文小编为大家详细介绍“Java怎么优雅的调用dubbo同时不使用其它jar包”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java怎么优雅的调用dubbo同时不使用其它jar包”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
1、正常dubbo调用流程
引入dubbo依赖
引入他人提供的clinet依赖包;
配置相同的注册中心,使用@Reference注解注入对应的service接口(注意是Reference是dubbo包下的,不是spring那个)
2、如果想在不引用他人jar包的情况下如何调用呢
dubbo泛化调用-dubbo原生支持的优雅方法
使用场景:
消费者不希望引入生产者提供的clinet依赖;
例如:消费者是一个基础服务,需要调用很多生产者的dubbo方法,那他就要引入很多的jar包;
消费者不使用java语言,而是使用其他的语言(例如:Python);
如何使用:
需要知道对方方法的全路径名称(interfaceName)
如果对方的dubbo有指定的版本号(version)和组(group)要指定一下,不然有很大可能会调用不通
要知道对方的注册中心地址和连接方式(如果是在同一个zk注册中心就更好了)
1.获取泛化对象
private GenericService getGenericService(String interfaceName, String version, String group) { ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); // set application ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setId(APPLICATION_ID); applicationConfig.setName(APPLICATION_ID); reference.setApplication(applicationConfig); // 通过zookeeper连接 RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress(zkAddress); registryConfig.setProtocol(ZOOKEEPER); registryConfig.setCheck(false); reference.setRegistry(registryConfig); // set timeout reference.setTimeout(syncForwardTimeout); // set retry times reference.setRetries(syncRetries); // set check reference.setCheck(false); // set generic reference.setGeneric(true); // set interface version if (version != null && version.length() != 0) { reference.setVersion(version); } // set interface name reference.setInterface(interfaceName); // set service id reference.setId(interfaceName); // set dubbo protocol reference.setProtocol(DUBBO); // if (group != null && group.length() != 0) { reference.setGroup(group); } // 从zookeeper获取缓存,从缓存中获取泛化 return ReferenceConfigCache.getCache().get(reference);}
2.泛化调用入参处理
private ResponseDataDto<R> invoke(GenericService genericService, UpDataReqDto upDataReqDto, String method) { String[] paramTypes = new String[1]; Object[] paramValues = new Object[1]; int i = 0; paramTypes[i] = upDataReqDto.getClass().getTypeName(); paramValues[i] = upDataReqDto; Object object = genericService.$invoke(method, paramTypes, paramValues); return JSON.parseObject(JSON.toJSONString(object), new TypeReference<ResponseDataDto<R>>(){});}
实现原理:
泛化调用的实现主要涉及两个filter
com.alibaba.dubbo.rpc.filter.GenericFilter
com.alibaba.dubbo.rpc.filter.GenericImplFilter
泛化调用的流程:
调用 <-> GenericImplFilter <-> 网络(RPC) <-> GenericFilter <-> 服务实现
泛化调用的核心源码:
GenericImplFilter://判断是不是泛化调用if (isCallingGenericImpl(generic, invocation)) { RpcInvocation invocation2 = new RpcInvocation(invocation); invocation2.put(GENERIC_IMPL_MARKER, true); String methodName = invocation2.getMethodName(); Class<?>[] parameterTypes = invocation2.getParameterTypes(); Object[] arguments = invocation2.getArguments(); String[] types = new String[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { types[i] = ReflectUtils.getName(parameterTypes[i]); } Object[] args; if (ProtocolUtils.isBeanGenericSerialization(generic)) { args = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { args[i] = JavaBeanSerializeUtil.serialize(arguments[i], JavaBeanAccessor.METHOD); } } else { args = PojoUtils.generalize(arguments); } if (RpcUtils.isReturnTypeFuture(invocation)) { invocation2.setMethodName($INVOKE_ASYNC); } else { invocation2.setMethodName($INVOKE); } invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES); invocation2.setParameterTypesDesc(GENERIC_PARAMETER_DESC); invocation2.setArguments(new Object[]{methodName, types, args}); return invoker.invoke(invocation2);}// 普通服务进行通用调用else if (isMakingGenericCall(generic, invocation)) { Object[] args = (Object[]) invocation.getArguments()[2]; if (ProtocolUtils.isJavaGenericSerialization(generic)) { for (Object arg : args) { if (byte[].class != arg.getClass()) { error(generic, byte[].class.getName(), arg.getClass().getName()); } } } else if (ProtocolUtils.isBeanGenericSerialization(generic)) { for (Object arg : args) { if (!(arg instanceof JavaBeanDescriptor)) { error(generic, JavaBeanDescriptor.class.getName(), arg.getClass().getName()); } } } invocation.setAttachment( GENERIC_KEY, invoker.getUrl().getParameter(GENERIC_KEY));}GenericFilter:if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC)) && inv.getArguments() != null && inv.getArguments().length == 3 && !GenericService.class.isAssignableFrom(invoker.getInterface())){ .......泛化调用处理逻辑...... }
读到这里,这篇“Java怎么优雅的调用dubbo同时不使用其它jar包”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341