泛型日志脱敏切面通过@Sensitive注解标记敏感字段,结合反射与泛型工具类递归处理任意类型参数及返回值,自动应用手机号、身份证等脱敏策略,无需为每个DTO重复编码。

用泛型实现日志脱敏切面,核心是让切面能自动识别并处理任意类型参数中的敏感字段(如手机号、身份证号、邮箱),而无需为每个 DTO 单独写逻辑。关键在于:泛型用于统一入参/返回值类型约束,实际脱敏靠反射 + 注解驱动 + 可配置规则。
定义脱敏注解 @Sensitive
先声明一个运行时保留的注解,标记哪些字段需要脱敏及脱敏方式:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sensitive {
SensitiveType value() default SensitiveType.DEFAULT;
// 可扩展:自定义掩码字符、前后保留位数等
int keepHead() default 2;
int keepTail() default 4;
}
再定义枚举 SensitiveType,比如:PHONE、ID_CARD、EMAIL、DEFAULT,每种对应不同脱敏逻辑(如手机号 → 138****1234)。
泛型脱敏工具类 SensitiveUtils
不依赖具体类型,用泛型方法递归处理对象树,支持嵌套、集合、Map:
立即学习“Java免费学习笔记(深入)”;
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 接收
Object obj,内部用instanceof和反射判断是否为需脱敏的 POJO/DTO - 对每个字段检查是否有
@Sensitive,有则调用对应脱敏策略 - 对
List、Set、Map等容器类型,递归调用自身(泛型擦除不影响运行时类型判断) - 基本类型、String、日期等直接跳过;null 值安全处理
示例片段:
public static <T> T desensitize(T data) {
if (data == null) return null;
Class<?> clazz = data.getClass();
if (clazz.isPrimitive() || clazz == String.class || isSimpleType(clazz)) {
return data;
}
return (T) doDesensitize(data);
}
泛型日志切面 LogDesensitizeAspect
使用 Spring AOP,切 Controller 或 Service 方法的参数和返回值,用泛型增强可复用性:
- 切点表达式匹配带敏感数据的方法,例如
@annotation(org.springframework.web.bind.annotation.PostMapping)或自定义注解@LogDesensitize - 通知方法声明为
<T> void around(ProceedingJoinPoint pjp, T...)实际不用泛型参数,而是通过反射获取 args 和 returnType - 对
pjp.getArgs()每个参数调用SensitiveUtils.desensitize(arg) - 对返回值
result同样脱敏后再返回:return SensitiveUtils.desensitize(result) - 日志打印前,对脱敏后的参数和结果格式化输出(避免原始敏感数据进日志)
使用示例与注意事项
在 DTO 中标记字段:
public class UserRequest {
private String username;
@Sensitive(SensitiveType.PHONE)
private String phone;
@Sensitive(SensitiveType.ID_CARD)
private String idCard;
private List<Address> addresses; // Address 内部也可含 @Sensitive 字段
}
Controller 方法无需改写,切面自动生效。注意几点:
- 确保 DTO 类非 final,字段非 private(或提供 getter,工具类用 getter 访问)
- 避免循环引用,脱敏工具需加 visited 缓存防栈溢出
- 生产环境建议关闭对高频接口(如心跳)的脱敏,可用注解开关或切点排除
- 敏感规则可外置到配置中心(如 Nacos),实现运行时动态更新脱敏策略

















