Spring Boot 利用AOP解析SPEL,实现更强大的日志记录

本文介绍如何使用Spring AOP和SpEL表达式动态生成带有详细描述的操作日志,通过具体代码示例展示了如何记录用户的具体操作内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提

今天在用AOP的环绕通知做用户操作记录时,发现一个小问题:怎么能动态的记录日志的备注?
比如用户添加一个资讯,那我们在日志记录上只能简单的看到一条 某某某添加一条资产,那么问题来了:添加一条什么资产呢?
往往我们想记录的日志记录不是这样的,我们想记录的是 某某某添加一条 XXXXX 资讯;这样我们的日志看起来就一清二楚了。

SPEL表达式

SpEL 使用 #{…} 作为定界符 , 所有在大括号中的字符都将被认为是 SpEL , SpEL 为 bean 的属性进行动态赋值提供了便利;

通过 SpEL 可以实现:
  • 通过 bean 的 id 对 bean 进行引用。
  • 调用方式以及引用对象中的属性。
  • 计算表达式的值
  • 正则表达式的匹配。

在前面我们了解了AOP的环绕通知的写法,今天我们只需要在上面加些处理的方法就好了,话不多说开始看代码吧!

在业务代码上的注解加上表达式

注意 #{#webLoginPojo.userName}这就是spel表达式

   /**
     * web用户登录
     * @param webLoginPojo 账号  密码  验证码
     * @param
     * @return
     */
    @OperLog(message = "登录:#{#webLoginPojo.userName}",operation = OperationType.LOGIN)
    @RequestMapping(value = "/webLogin")
    @ResponseBody
    public ResultInfo<Object> webLogin(@RequestBody WebLoginPojo webLoginPojo){
        try {
            System.out.println("欢迎登录");
            return new ResultInfo<Object>(ConnUtil.SUCCESS,"登录成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultInfo<Object>(ConnUtil.ERROR,"服务器异常");
    }

在自定义的切面处理类里加上这个代码

message:就是注入@OperLog时的message

    /**
     * 解析SPEL
     * @param message
     * @param joinPoint
     * @return
     */
    private String executeTemplate(String message, ProceedingJoinPoint joinPoint)throws Exception{

        ExpressionParser parser = new SpelExpressionParser();

        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

        String[] params = discoverer.getParameterNames(method);

        Object[] args = joinPoint.getArgs();

        EvaluationContext context = new StandardEvaluationContext();
        for (int len = 0; len < params.length; len++) {
            context.setVariable(params[len], args[len]);
        }
        return parser.parseExpression(message, new TemplateParserContext()).getValue(context, String.class);
    }

在原来的方法修改一下,调用executeTemplate()方法

		//获取操作
        OperLog myLog = method.getAnnotation(OperLog.class);
        if (myLog != null) {
            String message = myLog.message();
            String description = executeTemplate(message, proceedingJoinPoint);
            sysLog.setMessage(description);//保存日志备注
        }

这样 description这个最后得到的就是一个完整动态的日志
在这里插入图片描述

最后

谢谢大家的参考、阅读;
可能大家在实际写代码的过程中有不一样的异常出错,大家可以留言一起讨论学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值