不使用他人jar包情況下優(yōu)雅的進行dubbo調用詳解
更新時間:2022年09月28日 14:10:21 作者:spider集控團隊
這篇文章主要為大家介紹了不使用他人jar包情況下優(yōu)雅的進行dubbo調用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
1、正常dubbo調用流程
- 引入dubbo依賴
- 引入他人提供的clinet依賴包;
- 配置相同的注冊中心,使用@Reference注解注入對應的service接口(注意是Reference是dubbo包下的,不是spring那個)
2、如果想在不引用他人jar包的情況下如何調用呢?
dubbo泛化調用-dubbo原生支持的優(yōu)雅方法
使用場景:
- 消費者不希望引入生產者提供的clinet依賴; 例如:消費者是一個基礎服務,需要調用很多生產者的dubbo方法,那他就要引入很多的jar包;
- 消費者不使用java語言,而是使用其他的語言(例如:Python);
如何使用:
1.需要知道對方方法的全路徑名稱(interfaceName)
2.如果對方的dubbo有指定的版本號(version)和組(group)要指定一下,不然有很大可能會調用不通
3.要知道對方的注冊中心地址和連接方式(如果是在同一個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
1. com.alibaba.dubbo.rpc.filter.GenericFilter 2. com.alibaba.dubbo.rpc.filter.GenericImplFilter
- 泛化調用的流程:
- 調用 <-> GenericImplFilter <-> 網絡(RPC) <-> GenericFilter <-> 服務實現
- 泛化調用的核心源碼:
GenericImplFilter: ``` //判斷是不是泛化調用 if (isCallingGenericImpl(generic, invocation)) { RpcInvocation invocation2 = new RpcInvocation(invocation); /** * Mark this invocation as a generic impl call, this value will be removed automatically before passing on the wire. * See {@link RpcUtils#sieveUnnecessaryAttachments(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())){ .......泛化調用處理邏輯...... }
3、總結
- 從源碼設計來看泛化調用提供了在沒有接口依賴的情況下進行調用的解決方案;
- 從擴展上來看泛化調用的侵入性不強,可以很好的用于框架擴展;
以上就是不使用他人jar包情況下優(yōu)雅的進行dubbo調用詳解的詳細內容,更多關于不引用jar包調用dubbo的資料請關注腳本之家其它相關文章!
相關文章
Java中的FilterOutputStream 簡介_動力節(jié)點Java學院整理
FilterOutputStream 的作用是用來“封裝其它的輸出流,并為它們提供額外的功能”。它主要包括BufferedOutputStream, DataOutputStream和PrintStream。接下來通過本文給大家簡單介紹下FilterOutputStream知識,需要的朋友參考下吧2017-05-05詳解SpringBoot AOP 攔截器(Aspect注解方式)
這篇文章主要介紹了詳解SpringBoot AOP 攔截器 Aspect,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05解決MyBatisPlus的updateBatchById()批量修改失效問題
這篇文章主要介紹了解決MyBatisPlus的updateBatchById()批量修改失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08一篇文章教你如何在SpringCloud項目中使用OpenFeign
這篇文章主要介紹了SpringCloud 使用Open feign 優(yōu)化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-08-08idea中maven使用tomcat7插件運行run報錯Could not start T
這篇文章主要介紹了idea中maven使用tomcat7插件運行run報錯Could not start Tomcat問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09