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());
            }
        }
    
    }

     

  • 相关阅读:
    二、DBMS_JOB(用于安排和管理作业队列)
    Oracle 常用系统包
    DBMS_OUTPUT(用于输入和输出信息)
    C#获取当前主机硬件信息
    Centos安装mysql5.7
    Rsync安装和配置
    利用Docker编译Hadoop 3.1.0
    hadoop集群环境搭建
    axios请求、拦截器
    import时,什么时候使用花括号'{ }'
  • 原文地址:https://www.cnblogs.com/antonyhubei/p/13357040.html
Copyright © 2011-2022 走看看