日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

優化使用Feign進行Rpc調用,支持對象傳參自動轉換

作者:it夜貓who 更新時間: 2022-06-08 編程語言
  • 項目使用feign進行模塊間rpc調用解耦
  • RPC(Remote Procedure Call)遠程過程調用,簡單的理解是一個節點請求另一個節點提供的服務,調用本地接口一樣調用遠程接口的方式,就是RPC
  • 而Feign是Spring Cloud全家桶中推薦使用的RPC框架,使用了HTTP作為傳輸層協議,底層封裝的是Spring RestTemplate。
  • 是Netflix開發的聲明式、模板化的HTTP客戶端, Feign可以幫助我們更快捷、優雅地調用HTTP API。
    調用方通過創建一個Feign提供者接口(不需要實現),url+requestMapping指向http接口

V2通用接口主要增加了 對象傳參的支持,
調用鏈:

CommonFeignService -->ConsumerController–>SpringBeanInvoker–>SpringBeanInvokerImpl

如用戶新增接口

interface UserService{
    /**
     * 新增數據
     * 2020-09-01
     * @param user
     * @return
     * @author yuhui
     */
    int addUser(User user);
}

新版本feign接口調用

class SsoLoginServiceImpl{
    /**
     *部門單點登錄
     *部分實現
     */
    public String deptSsoLogin(String authorization, String uid, String userAccount, String userName, String deptName, String deptCode) throws UnknownHostException {
            //創建用戶對象。
            JSONObject user = new JSONObject();
            user.put("userAccount", userAccount);
            String password = Md5Crypt.md5Crypt("Qwer123$".getBytes());
            user.put("password", password);
            user.put("userName", userName);
            user.put("enabled", "1");
            user.put("userType", "0");
            user.put("userDesc", "通過單點登錄介入");
            //支持對象json傳參。
            request.setArgs(new Object[]{JSONObject.toJSONString(user)});
            String res = iCommonFeignService.autoJson2BeanInvoke(request);
    }
}

SpringBeanInvokerImpl核心代碼


class  SpringBeanInvokerImpl{
   /**
    * 1 根據入參參數類型與方法名直接查找對應類的方法. 匹配成功,則返回結果<br>
    * 2 若1失敗, 則遍歷目標類方法,找到與入參方法名匹配的目標方法名. 若參數數量與接口參數要求數量一致. 則3 <br>
    * 3 進行參數類型判斷匹配. 判斷接口入參類型, 嘗試json轉換, 若匹配成功,則返回結果,跳出循環.<br>
    * 本方法適應重載方法.即同名不同參的方法.<br>
    * 2019年9月5日上午10:05:13
    *
    * @param springBean
    * @param methodName
    * @param args
    * @return
    * @author whx
    */
   private Method getBeanMethodByJsonParams(Object springBean, String methodName, Object... args) {
   	Method method = null;

   	//根據參數類型精確匹配.
   	Class<?>[] parameterTypes = null;
   	if (args != null && args.length > 0) {
   		parameterTypes = new Class<?>[args.length];
   		for (int i = 0; i < args.length; i++) {
   			parameterTypes[i] = args[i].getClass();
   		}
   	}

   	try {
   		method = springBean.getClass().getMethod(methodName, parameterTypes);
   	} catch (NoSuchMethodException e) {
   		log.info("精確參數類型查找方法失敗,使用遍歷方法進行查找,并判斷入參類型是否與原始方法參數類型一致或入參類型是原始方法參數的子類/實現.");
   		Method[] methods = springBean.getClass().getMethods();
   		for (int i = 0; i < methods.length; i++) {
   			Method subMethod = methods[i];
   			if (subMethod.getName().equals(methodName)) {
   				Class<?>[] methodParamTypes = subMethod.getParameterTypes();
   				if (methodParamTypes == null || methodParamTypes.length <= 0) {
   					method = subMethod;
   				} else {
   					//如果參數類型長度不匹配.則直接返回
   					if (parameterTypes == null || (methodParamTypes.length != parameterTypes.length)) {
   						method = null;
   					} else {
   						//自動參數轉換
   						boolean paramMatch = true;
   						try {
   							Object[] params = parameterTypesCheck(methodParamTypes, args, false);
   							if (params.length == args.length) {
   								paramMatch = true;
   							}
   						} catch (Exception exception) {
   							exception.printStackTrace();
   						}
   						if (paramMatch) {
   							method = subMethod;
   							break;
   						}
   					}
   				}
   			}
   		}
   	} catch (SecurityException e) {
   		e.printStackTrace();
   	}

   	return method;
   }
}

原文鏈接:https://blog.csdn.net/YSOLA4/article/details/115105512

欄目分類
最近更新