优化使用Feign进行Rpc调用,支持对象传参自动转换

  • 项目使用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;
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

it夜猫who

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值