利用springAOP解耦业务代码

springAOP除了spring的事务管理,其实还可以利用aop实现代码的优化

业务场景:服务端对接App时,在app不希望去做强更的情况,可能需要对数据做一些版本的控制,不同的版本看到不同的数据。

表结构:
数据表:id(数据自增id) name(数据名称)
版本表:id(版本自增id) code(版本唯一code) name(版本名称)
版本关联数据表:id(自增id) type(不同数据对应不同的类型) data_id(数据id) version_id(版本id)

关联关系就是通过关联表把数据和版本关联起来,并增加数据类型来区分不同的数据(任务,活动,首页banner图)自定义

  1. 首先需要自定义一个注解,代表哪个方法需要做版本控制,value是用来在定义的时候传入数据类型
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface VersionControlAnno {
	
	String value();

}
  1. 定义处理版本控制的处理类,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;
	}
}
  1. 然后要做的就是在你需要做版本控制的方法上面加上注解,并标识当前要查的数据类型,可以看到我当前获取的是任务的数据,所以数据类型我定义的是“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版权协议,转载请附上原文出处链接和本声明。