当前位置:网站首页>关于自动重复调用接口的一种实现方式-反射
关于自动重复调用接口的一种实现方式-反射
2022-07-26 12:42:00 【在今晚的月色下刺猹】
问题
最近工作中碰到了一个需求,需要实现后台对接口的重复调用,具体需求是:
- 后台需要缓存接口调用的结果;
- 每隔一段时间就自动重复调用一次,刷新缓存中的结果数据;
- 前端调用接口的时候,会直接返回缓存数据,而不会真实地调用接口,获取数据。
想到的具体实现方案是:
- 缓存结果数据很简单,直接用AOP做接口增强就行了;
- 保存接口调用的状态,以便后面能自动重复调用接口;
- 使用定时任务或者延迟队列来实现自动调用。
实现
AOP做接口增强
因为这个不是本文重点,所以就不贴具体实现了,大致思路就是:创建一个切点,然后在方法运行前后增强从缓存中取结果和将结果存入缓存的操作就行了。
保存接口调用状态
这个是本文的重点,我们知道一个接口的定义要素有:类、方法名和参数,所以我们要存储的调用信息就是这些信息了,具体实现步骤如下:
- 创建一个接口调用信息的类
public class RequestObject implements Serializable {
// 类名
private String clazzName;
// 方法名
private String methodName;
// 参数对象
private Object[] params;
// 参数类型
private String[] paramTypeNames;
public String getClazzName() {
return clazzName;
}
public void setClazzName(String clazzName) {
this.clazzName = clazzName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Object[] getParams() {
return params;
}
public void setParams(Object[] params) {
this.params = params;
}
public String[] getParamTypeNames() {
return paramTypeNames;
}
public void setParamTypeNames(String[] paramTypeNames) {
this.paramTypeNames = paramTypeNames;
}
}
- 在AOP增强代码中保存调用接口的调用信息,至于这个对象存放在哪里就任君选择了。
// 用反射获取接口的各种信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
RequestObject requestObject = new RequestObject();
// 类名
Object target = joinPoint.getTarget();
requestObject.setClazzName(target.getClass().getName());
// 方法名
requestObject.setMethodName(method.getName());
// 参数值
Object[] args = joinPoint.getArgs();
requestObject.setParams(args);
// 参数类型
if (args != null && args.length > 0){
String[] typeNames = new String[args.length];
for (int i = 0; i < args.length; i++){
typeNames[i] = args[i].getClass().getName();
}
requestObject.setParamTypeNames(typeNames);
}
- 用定时任务、mq或者延迟队列来实现对接口的自动调用:取出调用信息对象,然后执行接口调用
public String test() throws Throwable{
RequestObject requestObject = (RequestObject) RedisUtils.get("key");
// 加载类对象
Class c = Class.forName(requestObject.getClazzName());
// 参数类型
String[] paramTypeNames = requestObject.getParamTypeNames();
// 生成方法对象
Method method;
if (paramTypeNames == null || paramTypeNames.length <= 0){
method = c.getMethod(requestObject.getMethodName());
}else {
Class[] paramTypeClass = new Class[paramTypeNames.length];
for (int i = 0; i < paramTypeNames.length; i++){
paramTypeClass[i] = Class.forName(paramTypeNames[i]);
}
method = c.getMethod(requestObject.getMethodName(), paramTypeClass);
}
// 方法的调用,参数是类的一个对象和参数值;
// 这里对象是从spring中获取的,你也可以用其他方式来生成对象,
// 毕竟类对象都已经有了,用类生成对象应该不是什么难事
Object result = method.invoke(ApplicationContextHolder.getBean(c), requestObject.getParams());
return result.toString();
}
到这里,这个功能就已经大致实现了,虽然不是很难,但是用反射实现接口的重复调用还是很有意思的,记录一下,开心~
边栏推荐
- Kubernetes----高级存储之PV和PVC简介
- UE5 官方案例Lyra 全特性详解 7.资源管理
- 0 basic programming resources (collect first ~ read slowly ~)
- Guys, how can CDC Oracle set the reading from the specified SCN number, or how to set the read-only full archive, not to read fast
- Understand test.py in gaitset
- Redis realizes single sign on -- system framework construction (I)
- LCD笔记(7)LCD驱动程序框架_配置时钟
- Ds-24c/dc220v time relay
- Interviewer: how to deal with high concurrency?
- 2022 employment season! Adobe helps creative industry workers break through the shackles of skills and return to the source of ability
猜你喜欢

Backtracking - 46. Full arrangement

食品安全 | 网购的自制食品就是健康食品?莫要陷入这些误区

A super easy-to-use artifact apifox, throw swagger a few streets... (glory Collection Edition)

Ds-112 time relay

0 basic programming resources (collect first ~ read slowly ~)

QT introduction and case explanation

新功能 | 智能开放搜索上线定制词权重模型

C regards type as generic type T and uses it as generic type of method

什么是回调函数,对于“回”字的理解

Kubernetes ---- life cycle introduction of PV and PVC
随机推荐
C语言文件知识点
Does anyone know where the retract of flinksql can be specified? Only api code settings can be seen in online materials
QT introduction and case explanation
编程式导航路由跳转到当前路由(参数不变), 多次执行会抛出NavigationDuplicated的警告错误?
Shell variables and references
Code examples explain the difference between [reentrant lock] and [non reentrant lock]?
LCD notes (6) LCD driver framework_ Configuration pin
Kubernetes----高级存储之PV和PVC简介
JDBC从连接池获取连接(Druid连接池)
笔记。。。。
新功能 | 智能开放搜索上线定制词权重模型
LCD笔记(5)LCD驱动程序框架_使用设备树
Redisson distributed lock usage example (I)
A super easy-to-use artifact apifox, throw swagger a few streets... (glory Collection Edition)
LCD笔记(4)分析内核自带的LCD驱动程序
Shell变量和引用
LCD笔记(6)LCD驱动程序框架_配置引脚
食品安全 | 随便果可以”随便“吃吗?
1-6月中国ADAS供应商占比9% 又一家零部件巨头全面布局智驾新赛道
Kubernetes - Introduction to PV and PVC of advanced storage