最近遇到一个新需求:用户多次点击提交订单发生多次扣款,一开始准备配置数据库事务,但后来发现这种方法白白浪费很多资源,就改为利用接口上的切面对请求做拦截,并将当前登陆的用户存进Redis缓存,废话不说了直接上代码;
AOP的应用(模拟请求拦截器):
/** * @author YHW * @ClassName: ApiMemberAspect * @Description: * @date 2019/3/21 8:54 */ @Aspect @Configuration public aspect ApiMemberAspect { private Logger logger = LoggerFactory.getLogger(getClass()); private static Gson gson = new Gson(); //切点绑在注解上方便重用! @Pointcut("@annotation(io.renren.common.annotation.RepetitionCheck)") public void ApiLogPointCut() { } @Before("ApiLogPointCut()") public void beforeCheck(JoinPoint joinPoint) throws Throwable { Object[] paramValues = joinPoint.getArgs(); String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames(); for(int i = 0; i < paramNames.length; i++){ if("payType".equals(paramNames[i]) && paramValues[i] != null){ if(!"membercard".equals(paramValues[i])){ return; } } } for(int i = 0; i < paramNames.length; i++){ if ("mobile".equals(paramNames[i]) && paramValues[i] != null) { String phone = (String)paramValues[i]; logger.info(phone); RedisUtils redisUtils = new RedisUtils(); if(redisUtils.get(phone) != null){ throw new RRException("操作超时,请等待一会后重试"); }else{ redisUtils.set(phone,phone); } } } } @After("ApiLogPointCut()") public void afterCheck(JoinPoint joinPoint) throws Throwable{ Object[] paramValues = joinPoint.getArgs(); String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames(); for(int i = 0; i < paramNames.length; i++){ if ("mobile".equals(paramNames[i]) && paramValues[i] != null) { String phone = (String)paramValues[i]; logger.info(phone); RedisUtils redisUtils = new RedisUtils(); if(redisUtils.get(phone) != null){ redisUtils.delete(phone); } } } } @AfterThrowing("ApiLogPointCut()") public void afterException(JoinPoint joinPoint) throws Throwable{ Object[] paramValues = joinPoint.getArgs(); String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames(); for(int i = 0; i < paramNames.length; i++) { if ("mobile".equals(paramNames[i]) && paramValues[i] != null) { String phone = (String)paramValues[i]; logger.info(phone); RedisUtils redisUtils = new RedisUtils(); if(redisUtils.get(phone) != null){ redisUtils.delete(phone); } } } } }
下面是注解类:
/** * @author YHW * @ClassName: RepetitionCheck * @Description: * @date 2019/3/21 8:58 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepetitionCheck { String value() default ""; }
关于Redis就不多提了,自己也是处于只会用用的阶段,以后学习完会单独开一篇Redis专题,就酱
原文地址:https://www.cnblogs.com/Joey44/p/10614968.html
时间: 2024-10-17 00:08:19