java中通过自定义注解+ aop实现操作日志自动采集,核心是定义@logoperation注解、编写@around切面拦截方法、用反射提取参数并脱敏、结合jackson序列化及异步写入提升性能与安全性。

Java中通过自定义注解 + AOP 实现操作日志的自动采集(含入参、出参、异常等),核心在于:定义注解、编写切面逻辑、结合反射提取参数值,并合理处理敏感信息与性能开销。
一、定义日志记录注解
创建一个用于标记需要记录操作日志的方法的自定义注解,支持配置是否记录入参/出参/异常、日志级别、业务类型等:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogOperation {
String value() default ""; // 业务描述,如"用户登录"
boolean recordRequest() default true; // 是否记录请求参数
boolean recordResponse() default true; // 是否记录返回结果
boolean recordException() default true; // 是否记录异常堆栈
String[] excludeFields() default {}; // 敏感字段白名单(如 password, token)
String logLevel() default "INFO"; // 日志级别
}
二、编写AOP切面统一拦截
使用 @Aspect 切面,在方法执行前后及异常时采集数据。关键点包括:
- 用
@Around拦截带@LogOperation的方法,获取注解元数据 - 通过
joinPoint.getArgs()获取原始入参;用joinPoint.getSignature()解析方法签名 - 捕获返回值(
proceed()结果)和异常(catch (Throwable e)) - 对参数/返回值做脱敏处理(如 JSON 序列化 + 排除敏感字段)
三、安全高效地序列化参数与响应
避免直接打印对象引用或泄露敏感信息:
- 使用 Jackson 或 FastJSON 的
ObjectMapper转 JSON,配合@JsonIgnore或自定义序列化器 - 运行时动态过滤字段:遍历参数对象属性,若属性名在
excludeFields()中则跳过 - 对大对象或流式内容(如
MultipartFile,InputStream)跳过记录,防止OOM或阻塞 - 加日志采样开关或异步写入(如用
AsyncAppender或发到消息队列),避免影响主流程性能
四、集成到 Spring Boot 项目中
确保切面生效并可配置:
- 启用 AOP:
@EnableAspectJAutoProxy(Spring Boot 默认已启用) - 切面类加上
@Component和@Aspect,确保被扫描到 - 可通过
@ConditionalOnProperty控制是否开启日志采集功能 - 推荐将日志内容封装为标准结构体(如
OperationLogDTO),便于后续接入ELK或审计系统
不复杂但容易忽略的是:方法重载时注解继承性、Lambda 表达式内方法无法被 AOP 拦截、以及 Controller 层参数绑定(如 @RequestBody)后原始字符串已不可见——这些需结合 HandlerMethodArgumentResolver 或 Filter 预处理补充。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











