7

Spring Boot 使用 AOP 记录日志 | 武培轩的博客

 3 years ago
source link: https://www.tianheyu.top/archives/aop-log
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Spring Boot 使用 AOP 记录日志

武培轩 2021年03月01日 20次浏览

在项目开发中经常,日志系统是必不可少的,特别是管理系统,对于重要的操作都会有操作日志,然而这个操作不需要我们在相应的方法中一个一个的去实现,这肯定是不合适的,这样的操作无疑是加大了开发量,而且不易维护,所以实际项目中总是利用AOP(Aspect Oriented Programming)即面向切面编程来记录系统中的操作日志。

下面就来介绍如何在 Spring Boot 中 使用 AOP 记录日志:

首先加入 AOP 依赖:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>

创建日志注解类

创建一个日志注解类,这样就可以在需要记录日志的方法上加上注解就可以记录日志了,注解内容如下:

@Target({ElementType.PARAMETER, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface AopLogger { String describe() default "";

配置 AOP 切面

定义一个 AopLoggerAspect 切面类,用 @Aspect 声明该类为切面类。

@Aspect@Componentpublic class AopLoggerAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("@annotation(com.wupx.aop.logger.annotation.AopLogger)") public void aopLoggerAspect() { * 环绕触发 * @param point * @return @Around("aopLoggerAspect()") public Object doAround(ProceedingJoinPoint point) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; HttpServletRequest request = servletRequestAttributes.getRequest(); Object result = null; long startTime = System.currentTimeMillis(); result = point.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); logger.error(throwable.getMessage()); String describe = getAopLoggerDescribe(point); if (StringUtils.isBlank(describe)) { describe = "-"; // 打印请求相关参数 logger.info("========================================== Start =========================================="); logger.info("Describe : {}", describe); // 打印请求 url logger.info("URL : {}", request.getRequestURL()); logger.info("URI : {}", request.getRequestURI()); // 打印 Http method logger.info("HTTP Method : {}", request.getMethod()); // 打印调用 controller 的全路径以及执行方法 logger.info("Class Method : {}.{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName()); // 打印请求的 IP logger.info("IP : {}", request.getRemoteAddr()); // 打印请求入参 logger.info("Request Args : {}", point.getArgs()); // 打印请求出参 logger.info("Response Args : {}", result); logger.info("Time Consuming : {} ms", System.currentTimeMillis() - startTime); logger.info("=========================================== End ==========================================="); return result; * 获取注解中对方法的描述信息 * @param joinPoint 切点 * @return describe public static String getAopLoggerDescribe(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); AopLogger controllerLog = method.getAnnotation(AopLogger.class); return controllerLog.describe();

其中 @Pointcut 是定义一个切点,后面跟随一个表达式,表达式可以定义为某个 package 下的方法,也可以是自定义注解等。

@Around 为在切入点前后织入代码,并且可以自由的控制何时执行切点。

接下来编写 Controller 层来进行测试:

@RestController@RequestMapping("/user")public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; @PostMapping @AopLogger(describe = "添加用户") public String addUser(@RequestBody User user) { UserEntity userEntity = new UserEntity(); BeanUtils.copyProperties(user, userEntity); return userService.addUser(userEntity);

只需要在接口上填写 @AopLogger 就可以记录操作日志。

启动服务,通过 PostMan 请求 http://localhost:8080/user 接口,输出的日志如下所示:

可以看到把入参、出参以及接口信息都记录了下来,是不是很简单呢,只需要简单几步就可以实现 AOP 日志,大家可以自己实践下。

本文的完整代码在 https://github.com/wupeixuan/SpringBoot-Learnaop-logger 目录下。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK