Spring Boot 使用 AOP 记录日志

前端 2023-07-05 17:29:38
47阅读

文中转载微信公众平台「武培轩」,创作者武培轩 。转截文中请联络武培轩微信公众号。

在新项目开发设计中常常,日志系统软件是不可或缺的,尤其是智能管理系统,针对关键的实际操作都是会有实际操作日志,殊不知这一实际操作不用我们在相对的方式 中一个一个的去完成,这肯定是不适合的,那样的实际操作毫无疑问是增加了开发量,并且不容易维护保养,因此具体新项目中一直运用AOP(Aspect Oriented Programming)即朝向横切面程序编写来纪录系统软件中的实际操作日志。

下边就来详细介绍怎样在 Spring Boot 中 应用 AOP 纪录日志:

添加依靠

最先添加 AOP 依靠:

 
  1. <dependency> 
  2.  <groupId>org.springframework.boot</groupId> 
  3.  <artifactId>spring-boot-starter-aop</artifactId> 
  4. </dependency> 

建立日志注释类

建立一个日志注释类,那样就可以在必须纪录日志的方式 上再加上注释就可以纪录日志了,注释內容以下:

 
  1. @Target({ElementType.PARAMETER, ElementType.METHOD}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Documented 
  4. public @interface AopLogger { 
  5.  
  6.     String describe() default ""

配备 AOP 横切面

界定一个 AopLoggerAspect 横切面类,用 @Aspect 申明此类为横切面类。

 
  1. @Component 
  2. public class AopLoggerAspect { 
  3.     private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
  4.  
  5.     @Pointcut("@annotation(com.wupx.aop.logger.annotation.AopLogger)"
  6.     public void aopLoggerAspect() { 
  7.     } 
  8.  
  9.     /** 
  10.      * 围绕开启 
  11.      * 
  12.      * @param point 
  13.      * @return 
  14.      */ 
  15.     @Around("aopLoggerAspect()"
  16.     public Object doAround(ProceedingJoinPoint point) { 
  17.         RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 
  18.         ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; 
  19.         HttpServletRequest request = servletRequestAttributes.getRequest(); 
  20.         Object result = null
  21.         long startTime = System.currentTimeMillis(); 
  22.         try { 
  23.             result = point.proceed(); 
  24.         } catch (Throwable throwable) { 
  25.             throwable.printStackTrace(); 
  26.             logger.error(throwable.getMessage()); 
  27.         } 
  28.         String describe = getAopLoggerDescribe(point); 
  29.         if (StringUtils.isBlank(describe)) { 
  30.             describe = "-"
  31.         } 
  32.         // 复印要求有关主要参数 
  33.         logger.info("========================================== Start =========================================="); 
  34.         logger.info("Describe       : {}", describe); 
  35.         // 复印要求 url 
  36.         logger.info("URL            : {}", request.getRequestURL()); 
  37.         logger.info("URI            : {}", request.getRequestURI()); 
  38.         // 复印 Http method 
  39.         logger.info("HTTP Method    : {}", request.getMethod()); 
  40.         // 复印启用 controller 的全途径及其实行方式  
  41.         logger.info("Class Method   : {}.{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName()); 
  42.         // 复印要求的 IP 
  43.         logger.info("IP             : {}", request.getRemoteAddr()); 
  44.         // 复印要求入参 
  45.         logger.info("Request Args   : {}", point.getArgs()); 
  46.         // 复印要求出参 
  47.         logger.info("Response Args  : {}", result); 
  48.         logger.info("Time Consuming : {} ms", System.currentTimeMillis() - startTime); 
  49.         logger.info("=========================================== End ==========================================="); 
  50.         return result; 
  51.     } 
  52.  
  53.     /** 
  54.      * 获得注释中对方式 的叙述信息内容 
  55.      * 
  56.      * @param joinPoint 相切 
  57.      * @return describe 
  58.      */ 
  59.     public static String getAopLoggerDescribe(JoinPoint joinPoint) { 
  60.         MethodSignature signature = (MethodSignature) joinPoint.getSignature(); 
  61.         Method method = signature.getMethod(); 
  62.         AopLogger controllerLog = method.getAnnotation(AopLogger.class); 
  63.         return controllerLog.describe(); 
  64.     } 

在其中 「@Pointcut」 是界定一个相切,后边追随一个关系式,关系式能够 界定为某一 package 下的方式 ,还可以是自定义注解等。

「@Around」 为在突破口前后左右织入编码,而且能够 随意的操纵什么时候实行相切。

检测

下面撰写 Controller 层来开展检测:

 
  1. @RestController 
  2. @RequestMapping("/user"
  3. public class UserController { 
  4.  
  5.     private final UserService userService; 
  6.  
  7.     public UserController(UserService userService) { 
  8.         this.userService = userService; 
  9.     } 
  10.  
  11.     @PostMapping 
  12.     @AopLogger(describe = "加上客户"
  13.     public String addUser(@RequestBody User user) { 
  14.         UserEntity userEntity = new UserEntity(); 
  15.         BeanUtils.copyProperties(user, userEntity); 
  16.         return userService.addUser(userEntity); 
  17.     } 

只必须在插口上填好 @AopLogger 就可以纪录实际操作日志。

运行服务项目,根据 PostMan 要求 http://localhost:8080/user 插口,輸出的日志以下所显示:

能够 见到把入参、出参及其插口信息内容都纪录了出来,是否非常简单呢,只必须简易两步就可以完成 AOP 日志,大伙儿能够 自身实践活动下。

文中的详细编码在 https://github.com/wupeixuan/SpringBoot-Learn 的 aop-logger 文件目录下。

the end
免责声明:本文不代表本站的观点和立场,如有侵权请联系本站删除!本站仅提供信息存储空间服务。