Java怎么优雅的调用dubbo同时不使用其它jar包

其他教程   发布日期:2023年07月11日   浏览次数:452

本文小编为大家详细介绍“Java怎么优雅的调用dubbo同时不使用其它jar包”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java怎么优雅的调用dubbo同时不使用其它jar包”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    1、正常dubbo调用流程

    引入dubbo依赖

    引入他人提供的clinet依赖包;

    配置相同的注册中心,使用@Reference注解注入对应的service接口(注意是Reference是dubbo包下的,不是spring那个)

    2、如果想在不引用他人jar包的情况下如何调用呢

    dubbo泛化调用-dubbo原生支持的优雅方法

    使用场景:

    消费者不希望引入生产者提供的clinet依赖;

    例如:消费者是一个基础服务,需要调用很多生产者的dubbo方法,那他就要引入很多的jar包;

    消费者不使用java语言,而是使用其他的语言(例如:Python);

    如何使用:

    1.需要知道对方方法的全路径名称(interfaceName)

    2.如果对方的dubbo有指定的版本号(version)和组(group)要指定一下,不然有很大可能会调用不通

    3.要知道对方的注册中心地址和连接方式(如果是在同一个zk注册中心就更好了)

    1.获取泛化对象

    1. private GenericService getGenericService(String interfaceName, String version, String group) {
    2. ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
    3. // set application
    4. ApplicationConfig applicationConfig = new ApplicationConfig();
    5. applicationConfig.setId(APPLICATION_ID);
    6. applicationConfig.setName(APPLICATION_ID);
    7. reference.setApplication(applicationConfig);
    8. // 通过zookeeper连接
    9. RegistryConfig registryConfig = new RegistryConfig();
    10. registryConfig.setAddress(zkAddress);
    11. registryConfig.setProtocol(ZOOKEEPER);
    12. registryConfig.setCheck(false);
    13. reference.setRegistry(registryConfig);
    14. // set timeout
    15. reference.setTimeout(syncForwardTimeout);
    16. // set retry times
    17. reference.setRetries(syncRetries);
    18. // set check
    19. reference.setCheck(false);
    20. // set generic
    21. reference.setGeneric(true);
    22. // set interface version
    23. if (version != null && version.length() != 0) {
    24. reference.setVersion(version);
    25. }
    26. // set interface name
    27. reference.setInterface(interfaceName);
    28. // set service id
    29. reference.setId(interfaceName);
    30. // set dubbo protocol
    31. reference.setProtocol(DUBBO);
    32. //
    33. if (group != null && group.length() != 0) {
    34. reference.setGroup(group);
    35. }
    36. // 从zookeeper获取缓存,从缓存中获取泛化
    37. return ReferenceConfigCache.getCache().get(reference);
    38. }

    2.泛化调用入参处理

    1. private ResponseDataDto<R> invoke(GenericService genericService, UpDataReqDto upDataReqDto, String method) {
    2. String[] paramTypes = new String[1];
    3. Object[] paramValues = new Object[1];
    4. int i = 0;
    5. paramTypes[i] = upDataReqDto.getClass().getTypeName();
    6. paramValues[i] = upDataReqDto;
    7. Object object = genericService.$invoke(method, paramTypes, paramValues);
    8. return JSON.parseObject(JSON.toJSONString(object), new TypeReference<ResponseDataDto<R>>(){});
    9. }

    实现原理:

    泛化调用的实现主要涉及两个filter

    com.alibaba.dubbo.rpc.filter.GenericFilter

    com.alibaba.dubbo.rpc.filter.GenericImplFilter

    泛化调用的流程:

    调用 <-> GenericImplFilter <-> 网络(RPC) <-> GenericFilter <-> 服务实现

    泛化调用的核心源码:

    1. GenericImplFilter:
    2. //判断是不是泛化调用
    3. if (isCallingGenericImpl(generic, invocation)) {
    4. RpcInvocation invocation2 = new RpcInvocation(invocation);
    5. /**
    6. * Mark this invocation as a generic impl call, this value will be removed automatically before passing on the wire.
    7. * See {@link RpcUtils#sieveUnnecessaryAttachments(Invocation)}
    8. */
    9. invocation2.put(GENERIC_IMPL_MARKER, true);
    10. String methodName = invocation2.getMethodName();
    11. Class<?>[] parameterTypes = invocation2.getParameterTypes();
    12. Object[] arguments = invocation2.getArguments();
    13. String[] types = new String[parameterTypes.length];
    14. for (int i = 0; i < parameterTypes.length; i++) {
    15. types[i] = ReflectUtils.getName(parameterTypes[i]);
    16. }
    17. Object[] args;
    18. if (ProtocolUtils.isBeanGenericSerialization(generic)) {
    19. args = new Object[arguments.length];
    20. for (int i = 0; i < arguments.length; i++) {
    21. args[i] = JavaBeanSerializeUtil.serialize(arguments[i], JavaBeanAccessor.METHOD);
    22. }
    23. } else {
    24. args = PojoUtils.generalize(arguments);
    25. }
    26. if (RpcUtils.isReturnTypeFuture(invocation)) {
    27. invocation2.setMethodName($INVOKE_ASYNC);
    28. } else {
    29. invocation2.setMethodName($INVOKE);
    30. }
    31. invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES);
    32. invocation2.setParameterTypesDesc(GENERIC_PARAMETER_DESC);
    33. invocation2.setArguments(new Object[]{methodName, types, args});
    34. return invoker.invoke(invocation2);
    35. }
    36. // 普通服务进行通用调用
    37. else if (isMakingGenericCall(generic, invocation)) {
    38. Object[] args = (Object[]) invocation.getArguments()[2];
    39. if (ProtocolUtils.isJavaGenericSerialization(generic)) {
    40. for (Object arg : args) {
    41. if (byte[].class != arg.getClass()) {
    42. error(generic, byte[].class.getName(), arg.getClass().getName());
    43. }
    44. }
    45. } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
    46. for (Object arg : args) {
    47. if (!(arg instanceof JavaBeanDescriptor)) {
    48. error(generic, JavaBeanDescriptor.class.getName(), arg.getClass().getName());
    49. }
    50. }
    51. }
    52. invocation.setAttachment(
    53. GENERIC_KEY, invoker.getUrl().getParameter(GENERIC_KEY));
    54. }
    55. GenericFilter
    56. if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC))
    57. && inv.getArguments() != null
    58. && inv.getArguments().length == 3
    59. && !GenericService.class.isAssignableFrom(invoker.getInterface())){
    60. .......泛化调用处理逻辑......
    61. }

    以上就是Java怎么优雅的调用dubbo同时不使用其它jar包的详细内容,更多关于Java怎么优雅的调用dubbo同时不使用其它jar包的资料请关注九品源码其它相关文章!