SpringBoot實(shí)戰(zhàn):輕松使用AOP+注解實(shí)現(xiàn)操作日志記錄
引言
在企業(yè)應(yīng)用開發(fā)中,操作日志記錄是確保系統(tǒng)安全性、可追溯性以及調(diào)試分析的重要手段之一。通過記錄用戶的操作行為,不僅可以幫助開發(fā)者快速定位問題,還能滿足審計(jì)和合規(guī)需求。本文旨在探討如何在SpringBoot應(yīng)用程序中通過AOP(面向切面編程)和自定義注解實(shí)現(xiàn)操作日志記錄,并將日志存儲(chǔ)到數(shù)據(jù)庫中。
AOP簡介
AOP(Aspect Oriented Programming)面向切面編程,是對(duì)OOP(Object-Oriented Programming)的一種補(bǔ)充。它允許開發(fā)者在不修改源代碼的情況下增加額外的功能,如日志記錄、事務(wù)管理、權(quán)限控制等。在SpringBoot中,AOP通過注解和動(dòng)態(tài)代理實(shí)現(xiàn),極大地簡化了橫切關(guān)注點(diǎn)的管理。
環(huán)境準(zhǔn)備
- JDK版本:JDK 17
- Spring Boot版本:Spring Boot 3.2.2
- MySQL版本:8.0.37
- 構(gòu)建工具:Maven
確保項(xiàng)目中包含Spring AOP的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
數(shù)據(jù)庫設(shè)計(jì)
首先,需要?jiǎng)?chuàng)建一個(gè)操作日志記錄表,用于存儲(chǔ)日志信息。以下是一個(gè)簡單的操作日志表結(jié)構(gòu)示例:
CREATE TABLE `sys_oper_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(50) DEFAULT NULL COMMENT '模塊標(biāo)題',
`business_type` varchar(20) DEFAULT NULL COMMENT '業(yè)務(wù)類型',
`method` varchar(100) DEFAULT NULL COMMENT '方法名稱',
`request_method` varchar(10) DEFAULT NULL COMMENT '請(qǐng)求方式',
`operator_type` varchar(10) DEFAULT NULL COMMENT '操作類別',
`oper_name` varchar(50) DEFAULT NULL COMMENT '操作人員',
`oper_url` varchar(255) DEFAULT NULL COMMENT '請(qǐng)求URL',
`oper_ip` varchar(50) DEFAULT NULL COMMENT '主機(jī)地址',
`oper_param` text COMMENT '請(qǐng)求參數(shù)',
`json_result` text COMMENT '返回參數(shù)',
`status` int DEFAULT NULL COMMENT '操作狀態(tài)',
`error_msg` varchar(200) DEFAULT NULL COMMENT '錯(cuò)誤消息',
`oper_time` datetime DEFAULT NULL COMMENT '操作時(shí)間',
`execute_time` bigint DEFAULT NULL COMMENT '執(zhí)行時(shí)長',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志記錄';
創(chuàng)建實(shí)體類
對(duì)應(yīng)上述數(shù)據(jù)庫表,創(chuàng)建一個(gè)系統(tǒng)日志實(shí)體類SysOperLog,使用Lombok簡化代碼:
@Data
@Schema(description = "操作日志記錄")
@TableName(value = "sys_oper_log")
public class SysOperLog implements Serializable {
// 省略字段定義,參考數(shù)據(jù)庫表結(jié)構(gòu)
}
創(chuàng)建注解
定義一個(gè)自定義注解@Log,用于標(biāo)記需要記錄日志的方法:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
String title() default "";
BusinessType businessType() default BusinessType.OTHER;
boolean isSaveRequestData() default true;
boolean isSaveResponseData() default true;
String[] excludeParamNames() default {};
}
// 業(yè)務(wù)操作類型枚舉
public enum BusinessType {
OTHER, INSERT, UPDATE, DELETE
// 可根據(jù)實(shí)際需要擴(kuò)展
}
創(chuàng)建切面類
使用@Aspect注解定義一個(gè)切面類LogAspect,用于攔截帶有@Log注解的方法,并記錄日志:
@Aspect
@Component
public class LogAspect {
@Autowired
private SysOperLogService sysOperLogService; // 假設(shè)的日志服務(wù)
@Pointcut("@annotation(com.example.demo.annotation.Log)")
public void logPointcut() {}
@Around("logPointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long executeTime = System.currentTimeMillis() - startTime;
// 收集日志信息,這里僅為示例
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Log logAnnotation = signature.getMethod().getAnnotation(Log.class);
// 省略日志信息組裝過程
// 保存日志
sysOperLogService.saveLog(log); // 假設(shè)的保存日志方法
return result;
}
}
注意:這里的saveLog方法需要根據(jù)實(shí)際業(yè)務(wù)邏輯進(jìn)行實(shí)現(xiàn),包括日志信息的詳細(xì)組裝和數(shù)據(jù)庫保存操作。
使用注解
在需要記錄日志的方法上添加@Log注解:
@Service
public class SomeService {
@Log(title = "用戶管理", businessType = BusinessType.UPDATE)
public void updateUserInfo(UserInfo userInfo) {
// 業(yè)務(wù)邏輯
}
}
總結(jié)
通過上述步驟,我們利用AOP和自定義注解在SpringBoot應(yīng)用中實(shí)現(xiàn)了操作日志的記錄。這種方式不僅減少了代碼冗余,提高了開發(fā)效率,還增強(qiáng)了系統(tǒng)的可維護(hù)性和可擴(kuò)展性。希望本文對(duì)你在實(shí)際開發(fā)中的日志記錄工作有所幫助。