SPEL+AOP记录系统操作日志

24 阅读1分钟

自定义日志注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    String value();
}

AOP

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(cn.zjamss.log.anno.OperationLog)")
    public void operationLogPointCut() {
    }

    @Around(value = "operationLogPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object res = point.proceed();
        ExpressionParser expressionParser = new SpelExpressionParser();
        EvaluationContext evaluationContext = new StandardEvaluationContext();
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        OperationLog operationLog = method.getAnnotation(OperationLog.class);
        String exp = operationLog.value();

        Parameter[] parameters = method.getParameters();
        Object[] args = point.getArgs();
        for (int i = 0; i < parameters.length; i++) {
            evaluationContext.setVariable(parameters[i].getName(), args[i]);
        }

        Expression expression = expressionParser.parseExpression(exp);
        String value = (String) expression.getValue(evaluationContext);
        System.out.println("Operation Log > " + value);
        return res;
    }
}

测试

@RestController
public class TestController {


    @RequestMapping("/test")
    @OperationLog("#user.username + ' 在 ' + T(java.time.LocalDateTime).now().format(T(java.time.format.DateTimeFormatter).ofPattern('yy-MM-dd HH:mm:ss')) + ' 登陆了系统'")
    public String login(User user) {
        return "Success";
    }
}

image.png

结果

image.png