zoukankan      html  css  js  c++  java
  • Spring AOP 学习之注解解决重复提交,异常日志处理

    1.AOP + Redis 解决重复提交

     重复提交是我们日常中比较频繁发生的事情,用户可以点击一个按钮多次,如未加相应的处理,就会请求后台多次,每次请求对后台服务来说都是一次性能的消耗,有些非幂等接口更是会有很多的业务问题,为此解决重复提交是一件非常重要的事情。当然解决重复提交也有很多种方法,如接口幂等,redis,数据库,mq等等,现讲解Spring + redis的方案解决重复提交,根据每次的请求路径+用户的请求sessionId来判别是否是同一个用户,通过判断用户请求的key是否在redis中存在来判别是否失效,话不多说,show me your code!

    1.1 先写注解

    /** * @version V1.0
     * @Description 防止重复提交
     * @date 2020/7/15 19:39.
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NoRepeatSubmit {
    
        /**
         * 设置请求锁定时间
         *
         * @return
         */
        int lockTime() default 3;
    
    }

    1.2 注解防止重复提交

    /** * @version V1.0
     * @Description 防止重复提交
     * @date 2020/7/15 19:46.
     */
    @Slf4j
    @Aspect
    @Component
    public class RepeatSubmitAspect {
    
        @Autowired
        private RedisTemplate<String, Integer> redisTemplate;
    
        @Pointcut("@annotation(noRepeatSubmit)")
        public void pointCut(NoRepeatSubmit noRepeatSubmit) {
        }
    
        @Around("pointCut(noRepeatSubmit)")
        public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) {
            ValueOperations<String, Integer> opsForValue = redisTemplate.opsForValue();
            try {
                int lockSeconds = noRepeatSubmit.lockTime();
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
                HttpServletRequest request = attributes.getRequest();
                String key = sessionId + ":" + request.getServletPath();
                // 如果缓存中有这个url视为重复提交
                if (opsForValue.get(key) == null) {
                    Object o = pjp.proceed();
                    opsForValue.set(key, 0, lockSeconds, TimeUnit.SECONDS);
                    return o;
                } else {
                    log.info("重复提交");
                    return RtnUtil.getFailMsgRtn("请勿重复提交~");
                }
            } catch (Throwable e) {
                e.printStackTrace();
                log.error("验证重复提交时出现未知异常!");
                return RtnUtil.getOkMsgRtn("验证重复提交时出现未知异常!");
            }
        }
    
    }

    1.3 接口加注解解决重复提交

        @NoRepeatSubmit(lockTime = 5)

     

    2. AOP + DB 解决异常日志记录写库

    2.1 先写注解

    /** * @version V1.0
     * @Description 描述
     * @date 2020/7/21 12:52.
     */
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface OperateLog {
        /**
         * 业务名称
         * @return
         */
        String businessName() default "操作日志";
        /**
         * 业务类型
         * @return
         */
        String businessType() default "system";
    }

    2.2 切面处理异常记录入库

    /** * @version V1.0
     * @Description 描述
     * @date 2020/7/21 12:53.
     */
    @Aspect
    @Component
    public class OperateLogAspect {
    
        @Pointcut(value = "@annotation(operateLog) && args(obj)")
        public void pointCut(OperateLog operateLog, Object obj) {
    
        }
    
        @AfterThrowing(pointcut = "pointCut(operateLog,obj)", throwing = "ex")
        public void afterThrowing(OperateLog operateLog, BusinessException ex, Object obj) {
            if (operateLog.businessType().equalsIgnoreCase("operator:bussiness")) {
                ParamObj paramObj = (ParamObj) obj;
               System.out.println("save::" + paramObj.toString());
            }
        }
    
    }

     

  • 相关阅读:
    013.ES6 -对象字面量增强型写法
    012. ES6
    011. ES6 语法
    10. 9. Vue 计算属性的setter和getter 以及 计算属性的缓存讲解
    4. Spring MVC 数据响应方式
    3. SpringMVC 组件解析
    9. Vue 计算属性
    【洛谷 2984】给巧克力
    【洛谷 1821】捉迷藏 Hide and Seek
    【洛谷 1821】银牛派对Silver Cow Party
  • 原文地址:https://www.cnblogs.com/antonyhubei/p/13357040.html
Copyright © 2011-2022 走看看