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

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

優(yōu)化使用Feign進行Rpc調(diào)用,支持對象傳參自動轉(zhuǎn)換

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

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

CommonFeignService -->ConsumerController–>SpringBeanInvoker–>SpringBeanInvokerImpl

如用戶新增接口

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

新版本feign接口調(diào)用

class SsoLoginServiceImpl{
    /**
     *部門單點登錄
     *部分實現(xiàn)
     */
    public String deptSsoLogin(String authorization, String uid, String userAccount, String userName, String deptName, String deptCode) throws UnknownHostException {
            //創(chuàng)建用戶對象。
            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 根據(jù)入?yún)?shù)類型與方法名直接查找對應(yīng)類的方法. 匹配成功,則返回結(jié)果<br>
    * 2 若1失敗, 則遍歷目標類方法,找到與入?yún)⒎椒ヅ涞哪繕朔椒? 若參數(shù)數(shù)量與接口參數(shù)要求數(shù)量一致. 則3 <br>
    * 3 進行參數(shù)類型判斷匹配. 判斷接口入?yún)㈩愋? 嘗試json轉(zhuǎn)換, 若匹配成功,則返回結(jié)果,跳出循環(huán).<br>
    * 本方法適應(yīng)重載方法.即同名不同參的方法.<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;

   	//根據(jù)參數(shù)類型精確匹配.
   	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("精確參數(shù)類型查找方法失敗,使用遍歷方法進行查找,并判斷入?yún)㈩愋褪欠衽c原始方法參數(shù)類型一致或入?yún)㈩愋褪窃挤椒▍?shù)的子類/實現(xiàn).");
   		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 {
   					//如果參數(shù)類型長度不匹配.則直接返回
   					if (parameterTypes == null || (methodParamTypes.length != parameterTypes.length)) {
   						method = null;
   					} else {
   						//自動參數(shù)轉(zhuǎn)換
   						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

欄目分類
最近更新