搜索
您的当前位置:首页正文

SpringAOP+自定义注解+Spel表达式实现审计日志

来源:爱够旅游网
SpringAOP+⾃定义注解+Spel表达式实现审计⽇志

1-简介

审计⽇记就是记录⽤户的操作记录

基于AOP动态代理 实现⾃定义审计⽇志注解, 并⽀持Spel表达式解析

2-实现

2-1 ⽇志存储实体类

@Data@Builder@ToString

public class AuditingLog { private String userId; // ⽤户id

private String userNickname; //⽤户昵称 private String operationInfo; //操作信息

private String interfaceName; // 调⽤的接⼝⽅法名 private String applicationName; // 调⽤的服务名 private LocalDateTime createTime; //操作时间}

2-2 ⾃定义审计⽇志注解

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE, ElementType.METHOD})public @interface AuditLog { String logInfo(); //⽇志信息}

2-3 ⽇志注解的AOP的切⾯

@Aspect@Component

public class AuditLogAOP {

@Value(\"${spring.application.name}\")

private String applicationName; //从配置⽂件获得服务名

// spel表达式解析器

private SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

// 参数名发现器

private DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); @Before(value = \"@annotation(enableAuditLog) || @within(enableAuditLog)\") public void getAutiLogInfo(JoinPoint joinPoint, AuditLog enableAuditLog){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); if (enableAuditLog == null) {

enableAuditLog = signature.getMethod().getAnnotation(AuditLog.class); }

// 构建⽇志存储对象

AuditingLog auditlog = AuditingLog.builder().applicationName(applicationName).createTime(LocalDateTime.now()).build(); auditlog.setUserId(xxx); // 从上下⽂获取当前操作的⽤户信息 auditlog.setUserNickname(xx);

// 设置操作的接⼝⽅法名

auditlog.setInterfaceName(signature.getDeclaringTypeName()+\".\"+signature.getName()); // 获得⽇志注解上⾃定义的⽇志信息

String logInfo = enableAuditLog.logInfo();

// Spel表达式解析⽇志信息 // 获得⽅法参数名数组

String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());

if (parameterNames != null && parameterNames.length > 0){

EvaluationContext context = new StandardEvaluationContext();

//获取⽅法参数值

Object[] args = joinPoint.getArgs(); for (int i = 0; i < args.length; i++) {

context.setVariable(parameterNames[i],args[i]); // 替换spel⾥的变量值为实际值, ⽐如 #user --> user对象 }

// 解析出实际的⽇志信息

String opeationInfo = spelExpressionParser.parseExpression(logInfo).getValue(context).toString(); auditlog.setOperationInfo(opeationInfo); }

// 打印⽇志信息

log.info(auditlog.toString());

//TODO 这时可以将⽇志信息auditlog进⾏异步存储,⽐如写⼊到⽂件通过logstash增量的同步到Elasticsearch或者DB }}

2-4 开启审计⽇志功能

在分布式项⽬中⼀般会将⽇志抽离出来公共调⽤, 所以为了⽅便的注⼊审计⽇志功能,可以编写对应 Enable注解

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Import({AuditLogAOP.class}) // 注⼊AOP切⾯到容器public @interface EnableAuditLog {}

3 使⽤

3-1 开启审计⽇志功能

在要使⽤审计⽇志功能的服务的⼊⼝类开启审计⽇志功能⽐如

@SpringBootApplication@EnableDiscoveryClient

@EnableAuditLog //开启审计⽇志public class UmsAdminApplication { public static void main(String[] args) {

SpringApplication.run(UmsAdminApplication.class,args); }}

3-2 在接⼝上使⽤

⽐如:

@AuditLog(logInfo = \"'新增管理员:'+ #user.username\") @PostMapping

public String addUser(@RequestBody User user){

return null; }

转载:https://blog.csdn.net/weixin_41347419/article/details/107573038

因篇幅问题不能全部显示,请点此查看更多更全内容

Top