- 项目使用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{
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", "通过单点登录介入");
request.setArgs(new Object[]{JSONObject.toJSONString(user)});
String res = iCommonFeignService.autoJson2BeanInvoke(request);
}
}
SpringBeanInvokerImpl核心代码
class SpringBeanInvokerImpl{
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;
}
}