有时候在写自定义注解时需要获取到方法上的参数,虽然要获取的参数都是同一个,但是可能因为入参的不同,数据结构的不同,从而导致不能准确的获取到,这时候我们可以通过spel表达式来获取。
spel:Spring Expression Language,这是一个强大的表达式,我们这里只用上了最简单的一种,其他的用法有兴趣的可以自己在网上查找资料。

1.创建注解

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

2.编写aop

@Aspect
@Component
public class DataFilterAop {

    /**
     * 监控这个注解
     */
    @Pointcut("@annotation(club.gggd.demo.anno.DataFilter)")
    public void pointCut() {
    }

    /**
     * 方法执行前
     * @param joinPoint
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint) {
        // 获取方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取注解
        DataFilter annotation = method.getAnnotation(DataFilter.class);
        String value = annotation.value();

        // 创建 SpEL 上下文
        StandardEvaluationContext context = new StandardEvaluationContext();
        // 设置方法参数作为变量
        Object[] args = joinPoint.getArgs();
        String[] parameterNames = signature.getParameterNames();
        for (int i = 0; i < args.length; i++) {
            // 将参数放入上下文
            context.setVariable(parameterNames[i], args[i]);
        }

        // 解析 EL 表达式
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(value);
        Object result = expression.getValue(context);

        // 处理解析结果
        System.out.println("解析到的结果为: " + result);

    }
}

3.在service层编写方法

@Override
// 注意:一定要在前面加 # 号,这个是el表达式的固定格式
@DataFilter(value = "#admin.name")
public int add(Admin admin, String table) {
    return mapper.insert(admin);
}

4.执行

解析到的结果为: zhangsan

5.额外内容

@Override
// 当然也可以直接获取参数
@DataFilter(value = "#table")
public int add(Admin admin, String table) {
    return mapper.insert(admin);
}