Spring AOP 使用 SPEL 表达式记录日志
需求来源
由于项目中需要记录操作日志,并且需要记录具体的细节操作,比如:新增用户,我们需要记录如下日志:
新增用户,用户名为:xxxx
获取参数xxxx的这个步骤,起始可以做到,但是一般做法是获取到方法的全部参数,这样记录的日志内容并不是很好看
所有我就想,会不会有支持 SPEL 表达式的方式,结果一百度,还真有,话不多说,现在记录下探索的过程
参考链接
实现过程
- 自定义注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuditLog {
String name() default "";
String code() default "";
//这个记录具体操作日志内容,可以支持SPEL表达式
String content() default "";
}
- 自定义切面,实现逻辑
@Log4j2
@Aspect
@Component
public class AuditAspect {
//解析spel表达式
ExpressionParser parser = new SpelExpressionParser();
//将方法参数纳入Spring管理
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
@Pointcut("@annotation(com.lcsoft.aop.AuditLog)")
public void logPointCut() {}
@Around("logPointCut()")
public Object invoked(ProceedingJoinPoint pjp) throws Throwable {
//获取参数对象数组
Object[] args = pjp.getArgs();
//获取方法
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
AuditLog log = method.getAnnotation(AuditLog.class);
String spel = log.content();
//获取方法参数名
String[] params = discoverer.getParameterNames(method);
//将参数纳入Spring管理
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
Expression expression = parser.parseExpression(spel);
spel = expression.getValue(context, String.class);
System.err.println("---------->>>>审计日志内容为:" + spel);
return pjp.proceed();
}
}
-
使用注解,在需要记录日志的方法上,添加注解
注意:spel表达式与不同字符串之间要有分隔,不然会报错
@ApiOperation(value = "获取我的应用")
@GetMapping("/mine")
@AuditAnnotation(content = "'角色id为' + #roleId + '的角色获取应用'")
public Result mine(@RequestParam(defaultValue = "", required = false) String roleId) {}
- 效果
---------->>>>审计日志内容为:角色id为373faa6a6f8541b8bfa4bf60bcce9318的角色获取应用
心得
整个过程还是比较简单的,我这里只是简单实现了功能,具体项目中尚需调整,比如:将日志记录到数据库或其他数据源等,这些具体怎么记录,每个人的具体实现就看你们自己啦!!!
加油!!!
版权声明:本文为qq_24986595原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。