• 自定义日志注解 + AOP实现记录操作日志



     
    需求:系统中经常需要记录员工的操作日志和用户的活动日志,简单的做法在每个需要的方法中进行日志保存操作,
    但这样对业务代码入侵性太大,下面就结合AOP和自定义日志注解实现更方便的日志记录
     
    首先看下一个简单的操作日志表
     
    action_log
    • id
    • subject(日志主题)
    • content(日志内容)
    • create_by
    • create_time

    日志主题可以用下面的枚举类来实现

    package cn.bounter.common.model;
    
    /**
     * 应用日志主题枚举类
     * @author simon
     *
     */
    public enum AppLogSubjectEnum {
    
       /** 客户 */
       CUSTOMER(1,"客户"),
       /** 商品 */
       COMMODITY(2,"商品"),
       /** 订单 */
       ORDER(3,"订单");
    
       private Integer value;
    
       private String name;
    
       private AppLogSubjectEnum(int value, String name) {
          this.value = value;
          this.name = name;
       }
    
       public Integer getValue() {
          return value;
       }
    
       public String getName() {
          return name;
       }
    
       /**
        * 自定义方法
        * 根据枚举值获取枚举字符串内容
        * @param value
        * @return
        */
       public static String stringOf(int value) {
          for(AppLogSubjectEnum oneEnum : AppLogSubjectEnum.values()) {
             if(oneEnum.value == value) {
                return oneEnum.getName();
             }
          }
          return null;
       }
    
    }

    然后让我们看下自定义注解

    package cn.bounter.common.model;
    
    import java.lang.annotation.*;
    
    /**
     * 应用日志注解
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface AppLog {
    
        /**
         * 日志主题
         * @return
         */
        AppLogSubjectEnum subject();
    
        /**
         * 日志内容
         * @return
         */
        String content() default "";
    }

    接下来就是重头戏基于自定义注解的切面了

    package cn.bounter.common.model;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    import java.time.LocalDateTime;
    
    /**
     * 应用日志切面
     */
    @Aspect
    @Component
    public class AppLogAspect {
    
        @Autowired
        private ActionLogService actionLogService;
    
        @Pointcut("@annotation(cn.bounter.common.model.AppLog)")
        public void appLogPointCut() {
        }
    
        @AfterReturning("appLogPointCut()")
        public void addActionLog(JoinPoint joinPoint) {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
    
            //获取注解
            AppLog appLog = method.getAnnotation(AppLog.class);
            if (appLog == null) {
                return;
            }
    
            //保存数据库
            actionLogService.save(
                    new ActionLog()
                    .setSubject(appLog.subject().getValue())
                    .setContent(appLog.content())
                    .setCreateBy(ShiroUtils.getUser())      //获取当前登录的用户
                    .setCreateTime(LocalDateTime.now())
            );
        }
    
    }

    到这里就差不多,最后让我们看下怎么使用自定义日志注解

    /**
     * 新增订单
     * @param order
     * @return
     */
    @AppLog(subject = AppLogSubjectEnum.ORDER, content = "新增")
    public void save(Order order) {
        orderService.save(order);
    }

    看完了之后是不是觉得挺简单哉!那就赶快自己动手试一试吧!

  • 相关阅读:
    Apache ab压力测试
    2、Android自动测试之Monkey工具
    1、Monkey环境搭建
    解决IDEA中,maven依赖不自动补全的问题
    Centos7解决在同一局域网内无法使用ssh连接
    sql草稿
    mysql三表联合查询,结果集合并
    vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单
    vue:使用不同参数跳转同一组件,实现动态加载图片和数据,以及利用localStorage和vuex持久化数据
    vue:解决使用param传参后,再次刷新页面会新增一个原有的tab
  • 原文地址:https://www.cnblogs.com/gdufs/p/10888536.html
Copyright © 2020-2023  润新知