springAOP除了spring的事务管理,其实还可以利用aop实现代码的优化
业务场景:服务端对接App时,在app不希望去做强更的情况,可能需要对数据做一些版本的控制,不同的版本看到不同的数据。
表结构:
数据表:id(数据自增id) name(数据名称)
版本表:id(版本自增id) code(版本唯一code) name(版本名称)
版本关联数据表:id(自增id) type(不同数据对应不同的类型) data_id(数据id) version_id(版本id)
关联关系就是通过关联表把数据和版本关联起来,并增加数据类型来区分不同的数据(任务,活动,首页banner图)自定义
- 首先需要自定义一个注解,代表哪个方法需要做版本控制,value是用来在定义的时候传入数据类型
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface VersionControlAnno {
String value();
}
- 定义处理版本控制的处理类,Pointcut匹配自定义的注解,基本的说明就是首先拿到当前方法上面的注解,并拿到定义的数据类型,接下来获取客户端传入的参数,因为入参我有一个基类,所以直接用基类转换就行了,拿到前端传入的版本code,并去查到与版本关联的数据,放入基类定义的一个dataList集合
@Aspect
@Component
public class VersionControlHandle{
ApplicationContext applicationContext;
@Autowired
MemberAccountService memberAccountService;
@Pointcut("@annotation(com.eighteen.playisportcommon.common.annotation.VersionControlAnno)")
public void wePointCut() {
}
@Around("wePointCut()")
public Object requestLimit(ProceedingJoinPoint joinPoint) {
Object proceed = null;
try {
String dataType = null;
Object[] args = joinPoint.getArgs();
// 通过方法的签名可以获取方法本身
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
if (method != null) {
// 拿到注解上面的数据类型
VersionControlAnno versionControlAnno = method.getAnnotation(VersionControlAnno.class);
if (versionControlAnno != null) {
dataType = versionControlAnno.value();
}
}
BaseVo baseVo = (BaseVo) args[0];
//拿到当前请求的版本code
Integer verCode = baseVo.getVerCode();
List<Integer> dataId = memberAccountService.getDataIdByVerCode(verCode, Integer.valueOf(dataType));
baseVo.setDataId(dataId);
proceed = joinPoint.proceed(args);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return proceed;
}
}
- 然后要做的就是在你需要做版本控制的方法上面加上注解,并标识当前要查的数据类型,可以看到我当前获取的是任务的数据,所以数据类型我定义的是“3”,根据自己的数据定义,在查询的mapper最后一个参数是从入参的基类拿到的dataList,就是我刚刚通过处理类查到的数据id集合,直接传进mapper就行了
@Override
@VersionControlAnno(value = "3")
public ResultVo selectTaskList(GetTaskListInVo getTaskListInVo) {
// 根据type获取不同类型的任务
List<TaskListVo> taskList = imsBhStApptaskMapper.selectTaskList(getTaskListInVo.getType(), imageUrl, getTaskListInVo.getDataId());
return ResultVo.success(taskList);
}
这样我们就可以利用AOP解决代码冗余问题,不用在每个地方重复去查询数据id,只需要封装好就行了,AOP可以利用的地方还很多,后续再更新
版权声明:本文为itchenguanxi原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。