一 前言

借助spring的AOP功能,我们可以将AOP应用至全局异常处理,全局请求拦截等,本篇文章的核心功能就是使用AOP实现日志记录,比如哪些用户进行了哪些操作,对于一个成功的项目这是必须记录的,故知识追寻者这边给出一个简单模型应用;

二 定义枚举

枚举定义的类型就是实现日志的哪些操作,如下所示,有些是登陆日志,有些是增删改查日志,不同的系统可以定义不同的日志,读者可以自由选择;

  1. public enum LogEnum {
  2.  
  3. UNOPERATE(0,"未定义操作"),
  4. SELECT(1,"查询"),
  5. INSERT(2,"添加"),
  6. UPDATE(3,"更新"),
  7. DELETE(4,"删除"),
  8. EXPORT(5,"excel导出"),
  9. LOGIN(6,"登陆"),
  10. LOGOUT(7,"登出"),
  11. ;
  12.  
  13. LogEnum( Integer code, String operate) {
  14. this.operate = operate;
  15. this.code = code;
  16. }
  17.  
  18. LogEnum(){
  19.  
  20. }
  21.  
  22. // 操作
  23. private String operate;
  24. // 操作码
  25. private Integer code;
  26.  
  27. public String getOperate() {
  28. return operate;
  29. }
  30.  
  31. public void setOperate(String operate) {
  32. this.operate = operate;
  33. }
  34.  
  35. public Integer getCode() {
  36. return code;
  37. }
  38.  
  39. public void setCode(Integer code) {
  40. this.code = code;
  41. }
  42. }

三 注解

使用注解的目的就是在哪些方法上使用注解,也就是标记这属于哪些操作,通过注解操作类型结合已经定义的枚举就可以简单的实现哪些方法上进行了哪些操作;

  1. @Documented
  2. @Target({ElementType.METHOD})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. public @interface MonitorLog {
  5.  
  6. /* *
  7. * @Author lsc
  8. * <p>日志内容 </p>
  9. * @Param []
  10. * @Return java.lang.String
  11. */
  12. String value() default "";
  13.  
  14. /* *
  15. * @Author lsc
  16. * <p>日志操作类型 </p>
  17. * @Param []
  18. * @Return int
  19. */
  20. LogEnum operateType() default LogEnum.UNOPERATE;
  21.  
  22. }

四 AOP切面

将注解设置为切点。将切点织入切面后使用环绕通知增强已经被注解标注的方法,此时就可以获得所有的注解操作,然后将日志记录入库,就可以简单实现用户的日志操作监控,当前提是在AOP中获得用户名,常见的shiro框架就有getSubject的方法获得用户名,当然根据不同的读者使用的技术不同进行获取,知识追寻者这边为了简单实现功能就没有使用一堆繁琐的方法去实现一个用户登陆认证系统;

  1. /**
  2. * @Author lsc
  3. * <p>日志aop切面 </p>
  4. */
  5.  
  6. @Aspect
  7. @Component
  8. public class LogAsp {
  9.  
  10. /* *
  11. * @Author lsc
  12. * <p> 设置切点</p>
  13. * @Param []
  14. * @Return void
  15. */
  16. @Pointcut("@annotation(com.zszxz.annotation.MonitorLog)")
  17. public void logPointCut() {
  18.  
  19. }
  20.  
  21. // 环绕通知
  22. @Around("logPointCut()")
  23. public Object around(ProceedingJoinPoint point) throws Throwable {
  24. // 开始时间
  25. LocalDateTime beginTime = LocalDateTime.now();
  26. // 执行方法
  27. Object result = point.proceed();
  28. // 结束时间
  29. LocalDateTime endTime = LocalDateTime.now();
  30. Duration duration = Duration.between(beginTime, endTime);
  31. // 操作时长
  32. long seconds = duration.getSeconds();
  33. // 保存日志
  34. saveLog(point,seconds);
  35. return result;
  36. }
  37.  
  38. private void saveLog(ProceedingJoinPoint point, long seconds){
  39. MethodSignature signature = (MethodSignature) point.getSignature();
  40. Method method = signature.getMethod();
  41. // 获得注解
  42. MonitorLog monitorLog = method.getAnnotation(MonitorLog.class);
  43. if (monitorLog!=null){
  44. // 获得操作类型
  45. LogEnum operateType = monitorLog.operateType();
  46. // 获得操作内容
  47. String value = monitorLog.value();
  48. System.out.printf("获得操作类型: %s , 获得操作内容: %s ",operateType.getCode(),value);
  49.  
  50. //请求的参数
  51. Object[] args = point.getArgs();
  52. try{
  53. List<Object> objects = Arrays.asList(args);
  54. System.out.println(objects);
  55. }catch (Exception e){
  56.  
  57. }
  58.  
  59. }
  60. }
  61. }

五 表现层

controller 所示,模拟进行查询用户操作的方法,并且在方法上标明注解这是个查询用户的方法,当访问此API时就会被AOP拦截;

  1. /**
  2. * @Author lsc
  3. * <p> </p>
  4. */
  5. @RestController
  6. public class UserController {
  7.  
  8. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  9.  
  10. @MonitorLog(value="查询用户",operateType = LogEnum.SELECT)
  11. @GetMapping("zszxz")
  12. public String getUser(String user){
  13. return "zszxz";
  14. }
  15.  
  16. }
  1.  

springboot-使用AOP日志拦截实现的更多相关文章

  1. springboot集成aop日志

    日常开发中假如是前后端完全分离,我们会习惯用浏览器去调用controller的接口来测试.这一个过程普通的日志功能会记录sql参数等一些基本信息.但是假如项目越来越庞大,我们的包越来越多,在维护项目和 ...

  2. Springboot的日志管理&Springboot整合Junit测试&Springboot中AOP的使用

    ==============Springboot的日志管理============= springboot无需引入日志的包,springboot默认已经依赖了slf4j.logback.log4j等日 ...

  3. 【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截

    一.前言 上一篇博客向大家介绍了Aop的概念,对切面=切点+通知 .连接点.织入.目标对象.代理(jdk动态代理和CGLIB代理)有所了解了.理论很强,实用就在这篇博客介绍. 这篇博客中,小编向大家介 ...

  4. SpringBoot学习笔记(七):SpringBoot使用AOP统一处理请求日志、SpringBoot定时任务@Scheduled、SpringBoot异步调用Async、自定义参数

    SpringBoot使用AOP统一处理请求日志 这里就提到了我们Spring当中的AOP,也就是面向切面编程,今天我们使用AOP去对我们的所有请求进行一个统一处理.首先在pom.xml中引入我们需要的 ...

  5. springboot整合aop实现网站访问日志记录

    目的: 统一日志输出格式,统计访问网站的ip. 思路: 1.针对不同的调用场景定义不同的注解,目前想的是接口层和服务层. 2.我设想的接口层和服务层的区别在于: (1)接口层可以打印客户端IP,而服务 ...

  6. 【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘

    前言 请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧. 实现 本篇AOP统一日志管理写法来源于国 ...

  7. aop 日志统一处理

    AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理.缓存.对象池管理以及日志记录.AOP将这些分散在各 ...

  8. Aop实现拦截方法参数

    对于spring框架来说,最重要的两大特性就是AOP 和IOC. 以前一直都知道有这两个东西,在平时做的项目中也常常会涉及到这两块,像spring的事务管理什么的,在看了些源码后,才知道原来事务管理也 ...

  9. SpringBoot切面Aop的demo简单讲解

    前言 本篇文章主要介绍的是SpringBoot切面Aop的demo简单讲解. SpringBoot Aop 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码. 切面(Aop) 一.概 ...

随机推荐

  1. Swift-技巧(三)使用元组(tuple)

    最近看 iOS 的官方功能的 Demo 时,发现代码中使用元组的地方很多,所以兴趣上来,查了下元组的出处. 在苹果的文档中就只有简短的两句,使用元组创建一个组合的值,从函数中返回多个值.元组中的可以使 ...

  2. spring boot+vue实现H5聊天室客服功能

    spring boot+vue实现H5聊天室客服功能 h5效果图 vue效果图 功能实现 spring boot + webSocket 实现 官方地址 https://docs.spring.io/ ...

  3. 手把手教你学Dapr - 7. Actors

    上一篇:手把手教你学Dapr - 6. 发布订阅 介绍 Actor模式将Actor描述为最低级别的"计算单元".换句话说,您在一个独立的单元(称为actor)中编写代码,该单元接收 ...

  4. 菜鸡的Java笔记 第二十一 final 关键字

    使用final定义类,属性,方法            final在一些书中被称为终结器,意思是:利用final定义的类不能够有子类,利用final定义的方法不能够被覆写,利用final定义的变量就成 ...

  5. 关于新手使用mpb开发代码的一些小知识

    mac 前端端口占用解决   1.查看8080端口,复制进程PID  lsof -i :8080 2.杀死进程 kill -9 「进程PID」   如果你的mac不能使用sudo解决办法   错误提示 ...

  6. 微信公众号生成海报(uniapp)

    前言 这几天接到一个需求,要在公众号内生成分享海报.之前有做过H5和小程序的,心想直接复制过来就行了.没想到踩了不少的坑,搞了好几天终于搞好了,特此分享一下,希望能对大家有所帮助. 效果图 代码实现 ...

  7. [atARC088F]Christmas Tree

    合并具有交换律,因此即将一个连通块(初始为空)与一条链合并(其中各选1点,初始直接替换) 把插入改为染色,等价于对树上的一条链(包括点和边)染色,其中恰好有1个已经被染色的点(初始任意) 对于&quo ...

  8. set比较大小

    #include <iostream> using namespace std; #include <set> class Person{ public: Person(str ...

  9. HAOI 2018 Round 1 题解

    无聊了开一套省选题刷刷--u1s1 感觉三个题都不错,难度也挺有梯度,是一道标准的省选难度的题(话说 CSP 前你刷省选题干嘛/ts/ts) 小 C 珂海星 T1:P4495 [HAOI2018]奇怪 ...

  10. 【R】如何将重复行转化为多列(一对一转化一对多)?

    目录 需求 方法一 方法二 需求 一个数据框一列或多列中有重复行,如何将它的重复行转化为多列?即本来两列一对一的关系,如何转化为一对多的关系?普通的spread函数实现较为麻烦. 示例数据如下: It ...