在若依框架中,AOP(Aspect-Oriented Programming,面向切面编程)是一种非常强大的工具,可以用来记录操作日志、监控系统性能、实现权限控制等功能。本文将详细介绍如何在若依框架中使用AOP记录操作日志,并深入解析其工作原理。
AOP是一种编程范式,旨在通过分离横切关注点(如日志记录、事务管理等)来提高代码的模块化程度。在Spring框架中,AOP通常用于拦截方法调用,并在方法执行前后插入额外的功能逻辑。
在若依框架中,日志记录是一个常见的需求,主要用于跟踪用户操作行为,便于后续审计和问题排查。具体需求包括:
确保项目中已经引入了Spring AOP相关的依赖。在Maven项目中,可以通过以下依赖引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
为了方便标记需要记录日志的方法,我们可以创建一个自定义注解@OperLog
:
import java.lang.annotation.*;
@Target(ElementType.METHOD) // 作用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
@Documented
public @interface OperLog {
String title() default ""; // 日志标题
String businessType() default ""; // 操作类型
}
接下来,我们编写一个切面类来拦截带有@OperLog
注解的方法,并记录日志。
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAspect {
// 定义切入点,匹配所有带有@OperLog注解的方法
@Pointcut("@annotation(com.example.demo.annotation.OperLog)")
public void operLogPointCut() {}
// 围绕通知,拦截方法并记录日志
@Around("operLogPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis(); // 方法开始时间
Object result; // 方法返回值
try {
// 执行目标方法
result = joinPoint.proceed();
} finally {
// 方法结束时间
long endTime = System.currentTimeMillis();
// 获取方法签名和参数
String methodName = joinPoint.getSignature().toShortString();
Object[] args = joinPoint.getArgs();
// 记录日志(此处可以扩展为保存到数据库)
System.out.println("Method: " + methodName);
System.out.println("Args: " + Arrays.toString(args));
System.out.println("Execution Time: " + (endTime - startTime) + "ms");
}
return result;
}
}
以下是上述切面类的工作流程图:
sequenceDiagram participant Controller as 控制器 participant Aspect as 切面类 participant Service as 服务层 Controller->>+Aspect: 调用带有@OperLog注解的方法 Aspect->>+Controller: 拦截方法,记录开始时间 Aspect->>+Service: 调用实际的服务方法 Service-->>-Aspect: 返回结果 Aspect->>+Controller: 记录结束时间及日志 Aspect-->>-Controller: 返回结果给控制器
在实际项目中,日志记录不仅仅打印到控制台,还需要持久化到数据库或其他存储介质中。若依框架通常会将日志信息存储到数据库表中,例如sys_oper_log
表。
CREATE TABLE sys_oper_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(500), -- 日志标题
method VARCHAR(500), -- 方法名称
params TEXT, -- 请求参数
ip VARCHAR(50), -- 操作者IP
execution_time INT, -- 执行时长
create_time DATETIME -- 创建时间
);
在日志记录过程中,如果目标方法抛出异常,也需要捕获并记录异常信息。可以在around
通知中添加异常处理逻辑:
catch (Throwable e) {
// 记录异常信息
System.out.println("Exception: " + e.getMessage());
throw e; // 继续向外抛出异常
}
AOP虽然强大,但可能会对系统性能产生一定影响。因此,在实际应用中需要注意以下几点: