You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析@ModelAttribute作为方法参数的切入点表达式并拦截对应控制器方法

拦截使用全局@ModelAttribute参数的控制器方法实现方案

这个问题可以通过Spring AOP的切面机制来解决,核心是编写精准的切入点表达式,匹配所有带有@ModelAttribute("key")参数的控制器方法,下面一步步给你讲清楚实现方式:

1. 编写精准的切入点表达式

要定位到所有使用全局@ModelAttribute("key")作为参数的控制器方法,我们需要用Spring AOP的切入点表达式匹配方法参数上的注解。正确的表达式写法如下:

@Pointcut("execution(* *..*Controller.*(.., @org.springframework.web.bind.annotation.ModelAttribute(\"key\") (*), ..))")

表达式细节解释:

  • execution(* *..*Controller.*(..)):基础匹配规则,覆盖所有包下名称以Controller结尾的类中的任意方法
  • .., @org.springframework.web.bind.annotation.ModelAttribute("key") (*), ..:表示方法参数列表中任意位置存在一个被@ModelAttribute("key")标注的参数,前后可以有其他任意数量的参数。这里的(*)表示参数类型不限(如果你的key固定是boolean类型,也可以写成(boolean)来做更精准的匹配)

如果只想拦截带有@RequestMapping的请求处理方法(过滤掉控制器中的非请求方法),可以给切入点加上额外的匹配条件:

@Pointcut("execution(* *..*Controller.*(.., @org.springframework.web.bind.annotation.ModelAttribute(\"key\") (*), ..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")

2. 实现拦截切面

接下来创建一个切面类,用@Aspect和@Component注解标记,让Spring容器管理它,并编写具体的拦截逻辑:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class GlobalKeyAttributeInterceptor {

    // 定义切入点
    @Pointcut("execution(* *..*Controller.*(.., @org.springframework.web.bind.annotation.ModelAttribute(\"key\") (*), ..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void methodsUsingGlobalKey() {}

    // 前置通知:在方法执行前触发拦截逻辑
    @Before("methodsUsingGlobalKey()")
    public void interceptTargetMethod(JoinPoint joinPoint) {
        // 获取被拦截方法的完整路径信息
        String methodFullName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        System.out.println("拦截到使用全局@ModelAttribute(\"key\")的控制器方法:" + methodFullName);

        // 如果需要获取该参数的具体值,可以遍历方法参数
        Object[] methodArgs = joinPoint.getArgs();
        for (Object arg : methodArgs) {
            if (arg instanceof Boolean) {
                Boolean keyValue = (Boolean) arg;
                System.out.println("全局key参数的当前值为:" + keyValue);
                // 这里可以添加你的业务逻辑,比如参数校验、日志记录、权限校验等
            }
        }
    }
}

3. 关键注意事项

  • 确保项目引入Spring AOP依赖:如果是Spring Boot项目,直接引入spring-boot-starter-aop即可;如果是传统Spring项目,需要引入spring-aspects和aspectjweaver依赖。
  • 切面类必须被Spring容器扫描到,要确保它所在的包在Spring的组件扫描范围内。
  • 除了@Before通知,你还可以根据需求使用@Around、@After等通知类型,实现更复杂的拦截逻辑(比如修改参数、控制方法执行流程、处理返回值等)。

内容的提问来源于stack exchange,提问作者user3484626

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:16:24