zoukankan      html  css  js  c++  java
  • springboot—spring aop 实现系统操作日志记录存储到数据库

    原文:https://www.jianshu.com/p/d0bbdf1974bd

    采用方案: 使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志
    缺点是要针对每个不同的注解标志进行分别取注解标志,获取参数进行日志记录输出

    1. 需要引用的依赖

    <!--spring切面aop依赖-->
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
    在application.properties文件里加这样一条配置
    spring.aop.auto=true //这个配置我的例子中没有加 也正常运行
    

    2. 创建实体类

    public class SysLog implements Serializable {
        private Long id;
    
        private String username; //用户名
    
        private String operation; //操作
    
        private String method; //方法名
    
        private String params; //参数
    
        private String ip; //ip地址
    
        private Date createDate; //操作时间
        //创建getter和setter方法
    }
    

    3. 使用spring 的 aop 技术切到自定义注解上,所以先创建一个自定义注解类

    import java.lang.annotation.*;
    
    /**
     * 自定义注解类
     */
    @Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
    @Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
    @Documented //生成文档
    public @interface MyLog {
        String value() default "";
    }
    

    4. 创建aop切面实现类

    import com.alibaba.fastjson.JSON;
    import com.qfedu.rongzaiboot.annotation.MyLog;
    import com.qfedu.rongzaiboot.entity.SysLog;
    import com.qfedu.rongzaiboot.service.SysLogService;
    import com.qfedu.rongzaiboot.utils.HttpContextUtils;
    import com.qfedu.rongzaiboot.utils.IPUtils;
    import com.qfedu.rongzaiboot.utils.ShiroUtils;
    import org.aspectj.lang.JoinPoint;
    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 javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    /**
     * 系统日志:切面处理类
     */
    @Aspect
    @Component
    public class SysLogAspect {
    
        @Autowired
        private SysLogService sysLogService;
    
        //定义切点 @Pointcut
        //在注解的位置切入代码
        @Pointcut("@annotation( com.qfedu.rongzaiboot.annotation.MyLog)")
        public void logPoinCut() {
        }
    
        //切面 配置通知
        @AfterReturning("logPoinCut()")
        public void saveSysLog(JoinPoint joinPoint) {
            System.out.println("切面。。。。。");
            //保存日志
            SysLog sysLog = new SysLog();
    
            //从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //获取切入点所在的方法
            Method method = signature.getMethod();
    
            //获取操作
            MyLog myLog = method.getAnnotation(MyLog.class);
            if (myLog != null) {
                String value = myLog.value();
                sysLog.setOperation(value);//保存获取的操作
            }
    
            //获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            //获取请求的方法名
            String methodName = method.getName();
            sysLog.setMethod(className + "." + methodName);
    
            //请求的参数
            Object[] args = joinPoint.getArgs();
            //将参数所在的数组转换成json
            String params = JSON.toJSONString(args);
            sysLog.setParams(params);
    
            sysLog.setCreateDate(new Date());
            //获取用户名
            sysLog.setUsername(ShiroUtils.getUserEntity().getUsername());
            //获取用户ip地址
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            sysLog.setIp(IPUtils.getIpAddr(request));
    
            //调用service保存SysLog实体类到数据库
            sysLogService.save(sysLog);
        }
    
    }
    

    5. 接下来就可以在需要监控的方法上添加 aop的自定义注解

    格式为 @+自定义注解的类名 @MyLog

    //例如在contoller类的方法上加注解
    @RestController
    @RequestMapping("/sys/menu")
    public class SysMenuController extends AbstractController {
    
        @Autowired
        private SysMenuService sysMenuService;
    
        @MyLog(value = "删除菜单记录")  //这里添加了AOP的自定义注解
        @PostMapping("/del")
        public R deleteBatch(@RequestBody Long[] menuIds) {
            for (Long menuId : menuIds) {
                if (menuId <= 31) {
                    return R.error("系统菜单,不能删除");
                }
            }
            sysMenuService.deleteBatch(menuIds);
    
            return R.ok("删除成功");
        }
    }
    

    6. 执行上面的方法操作后,会将记录保存到数据库

     
     
     


    作者:东方舵手
    链接:https://www.jianshu.com/p/d0bbdf1974bd
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    MySQL之IDE工具介绍及数据备份(数据库导入,导出)
    jmeter test Fragment
    python创建虚拟环境
    遇到的问题
    文件操作
    六、迭代器与生成器
    五、IO编程
    简单的例子
    四、函数
    三、集合与格式化
  • 原文地址:https://www.cnblogs.com/shihaiming/p/9565892.html
Copyright © 2011-2022 走看看