Spring AOP 使用 SPEL 表达式记录日志

Spring AOP 使用 SPEL 表达式记录日志

需求来源

由于项目中需要记录操作日志,并且需要记录具体的细节操作,比如:新增用户,我们需要记录如下日志:
新增用户,用户名为:xxxx
获取参数xxxx的这个步骤,起始可以做到,但是一般做法是获取到方法的全部参数,这样记录的日志内容并不是很好看
所有我就想,会不会有支持 SPEL 表达式的方式,结果一百度,还真有,话不多说,现在记录下探索的过程

参考链接

实现过程

  1. 自定义注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuditLog {

    String name() default "";

    String code() default "";

	//这个记录具体操作日志内容,可以支持SPEL表达式
    String content() default "";
}
  1. 自定义切面,实现逻辑
@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();
    }
}
  1. 使用注解,在需要记录日志的方法上,添加注解
    注意:spel表达式与不同字符串之间要有分隔,不然会报错
    @ApiOperation(value = "获取我的应用")
    @GetMapping("/mine")
    @AuditAnnotation(content = "'角色id为' + #roleId + '的角色获取应用'")
    public Result mine(@RequestParam(defaultValue = "", required = false) String roleId) {}
  1. 效果
---------->>>>审计日志内容为:角色id为373faa6a6f8541b8bfa4bf60bcce9318的角色获取应用

心得

整个过程还是比较简单的,我这里只是简单实现了功能,具体项目中尚需调整,比如:将日志记录到数据库或其他数据源等,这些具体怎么记录,每个人的具体实现就看你们自己啦!!!

加油!!!

你可能感兴趣的:(java)