基于Spring AOP实现自定义注解记录接口日志
本文最后更新于56 天前,其中的信息可能已经过时,如有错误请发送邮件到sherry.rain@qq.com

简介

本文将详细介绍如何使用Spring AOP和自定义注解来实现接口日志的记录,并扩展功能实现将日志数据记录到数据库、记录接口详情备注、记录调用用户和接口的调用速度。我们将使用MyBatis-Plus来操作数据库,并使用YAML格式的配置文件。此外,我们还会给出表的设计、表的创建和运行测试的示例,以展示使用效果。

1. 环境准备

在开始之前,确保你已经具备以下环境:

  • JDK 8+
  • Maven
  • Spring Boot
  • MyBatis-Plus

2. 创建Spring Boot项目

首先,我们需要创建一个Spring Boot项目。你可以使用Spring Initializr来快速创建一个基础的Spring Boot项目,添加所需的依赖。

3. 创建自定义注解

我们需要创建一个自定义注解来标记需要记录日志的接口。在项目中创建一个@Loggable注解:

javaimport java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {

    String value() default ""; // 接口详情备注

    boolean recordUser() default false; // 是否记录调用用户
}

4. 创建切面类

接下来,我们需要创建一个切面类来实现接口日志的记录。在项目中创建一个LoggingAspect切面类:

javaimport org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Aspect
@Component
public class LoggingAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Autowired
    private LogRepository logRepository;

    @Before("@annotation(com.example.demo.Loggable)")
    public void logBefore(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        logger.info("Before method: {}", methodName);

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Loggable loggable = method.getAnnotation(Loggable.class);

        String detail = loggable.value();
        boolean recordUser = loggable.recordUser();

        logRepository.save(new Log(null, methodName, "Before method - " + detail, new Date(), null));

        if (recordUser) {
            // 记录调用用户的逻辑
        }
    }

    @AfterReturning(pointcut = "@annotation(com.example.demo.Loggable)", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        logger.info("After method: {}", methodName);

        logRepository.save(new Log(null, methodName, "After method", new Date(), null));
    }

    @AfterThrowing(pointcut = "@annotation(com.example.demo.Loggable)", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {
        String methodName = joinPoint.getSignature().getName();
        logger.error("Exception in method: {}", methodName, exception);

        logRepository.save(new Log(null, methodName, "Exception in method", new Date(), null));
    }

    @Around("@annotation(com.example.demo.Loggable)")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        Object result = joinPoint.proceed();

        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;

        logger.info("Method execution time: {} ms", executionTime);

        logRepository.save(new Log(null, joinPoint.getSignature().getName(), "Execution time: " + executionTime + " ms", new Date(), null));

        return result;
    }
}

5. 配置MyBatis-Plus和YAML

pom.xml文件中添加MyBatis-Plus和MySQL驱动的依赖:

xml<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

application.yaml文件中配置数据库连接和MyBatis-Plus:

yamlspring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: your_username
    password: your_password
  jpa:
    hibernate:
      ddl-auto: none
    show-sql: true

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true

6. 创建日志表

我们需要创建一个logs表来存储日志数据。在MySQL数据库中执行以下SQL语句创建表:

sqlCREATE TABLE `logs` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `method_name` varchar(255) DEFAULT NULL,
  `log_message` varchar(255) DEFAULT NULL,
  `created_date` datetime DEFAULT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

7. 创建日志实体类和Repository

创建一个Log实体类和一个LogRepository接口。在项目中创建一个Log实体类:

javaimport com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("logs")
public class Log {

    private Long id;

    private String methodName;

    private String logMessage;

    private Date createdDate;

    private String userName;
}

然后,创建一个LogRepository接口:

javaimport com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;

@Repository
public interface LogRepository extends BaseMapper<Log> {
}

8. 运行测试

现在,我们已经完成了基于Spring AOP实现自定义注解记录接口日志的配置。运行Spring Boot应用程序,并调用带有@Loggable注解的接口方法,你将能够在日志中看到相应的日志记录,并将日志数据记录到数据库中。

java@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    @Loggable(value = "获取用户信息", recordUser = true)
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

9. 数据库中的日志数据

下面展示一下表中的数据样例:

id method_name log_message created_date user_name
1 getUserById Before method - 获取用户信息 2022-01-01 12:00:00 user1
2 getUserById After method 2022-01-01 12:01:00 null
3 getUserById Execution time: 100 ms 2022-01-01 12:01:30 null
4 getUserById Before method - 获取用户信息 2022-01-01 12:02:00 user2
5 getUserById Exception in method 2022-01-01 12:02:10 null

结论

本文详细介绍了如何使用Spring AOP和自定义注解来实现接口日志的记录,并扩展功能实现将日志数据记录到数据库、记录接口详情备注、记录调用用户和接口的调用速度。我们使用了MyBatis-Plus来操作数据库,并使用YAML格式的配置文件。通过实现示例,我们展示了使用效果,并给出了表的设计和创建的示例,以及数据库中的日志数据样例。希望本文能够帮助你实现接口日志记录的需求,并理解如何使用MyBatis-Plus和YAML配置文件。

作者:Sry0
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0协议。转载请注明文章地址及作者
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇