Aspect中@PutMapping注解失效问题求助
先把你提供的切面代码贴出来方便分析:
@Pointcut("execution(* com.api.webservice.controller.*.*(..)) " + "&& (@annotation(org.springframework.web.bind.annotation.PostMapping) || " + "@annotation(org.springframework.web.bind.annotation.PutMapping) || " + "@annotation(org.springframework.web.bind.annotation.DeleteMapping))") public void pointCut() {} @Around("pointCut()") public Object handleMethod(ProceedingJoinPoint pjp) throws Throwable { ...... }
根据你描述的Post/Delete能正常触发、Put不行的情况,我整理了几个最可能的排查方向:
1. 修正切入点表达式的转义错误(最大概率原因)
你代码里用了&&,这是HTML转义字符,但在Java字符串中,逻辑与运算符应该直接写&&。如果代码里保留&&,Spring解析切入点表达式时会把它当作普通字符串的一部分,导致整个表达式逻辑失效——Post/Delete可能是碰巧因为其他逻辑触发,而Put的匹配规则完全被破坏了。
解决方法:把&&替换成&&,修正后的切入点表达式如下:
@Pointcut("execution(* com.api.webservice.controller.*.*(..)) " + "&& (@annotation(org.springframework.web.bind.annotation.PostMapping) || " + "@annotation(org.springframework.web.bind.annotation.PutMapping) || " + "@annotation(org.springframework.web.bind.annotation.DeleteMapping))")
2. 确认@PutMapping的注解归属
检查控制器方法上的@PutMapping是否导入了正确的包:必须是org.springframework.web.bind.annotation.PutMapping,而不是其他框架(比如javax.servlet或第三方库)的同名注解。
验证方法:点击控制器里的@PutMapping查看导入路径,如果不是Spring的包,替换成正确的导入语句:
import org.springframework.web.bind.annotation.PutMapping;
3. 检查@PutMapping的标注位置
你的切入点表达式是匹配方法上的注解,如果@PutMapping被标注在控制器类上,而不是具体的方法上,切面就无法匹配到。
解决方法:确保@PutMapping直接标注在需要被拦截的方法上,而非类级别。
4. 验证控制器方法是否在execution表达式范围内
你的execution表达式是com.api.webservice.controller.*.*(..),这个表达式只匹配controller包下直接的类中的方法,不包含子包的类。如果Put方法所在的控制器在controller的子包(比如com.api.webservice.controller.v1),就会被漏掉。
解决方法:把表达式改成com.api.webservice.controller..*(..)(两个点..表示包含所有子包):
@Pointcut("execution(* com.api.webservice.controller..*(..)) " + "&& (@annotation(org.springframework.web.bind.annotation.PostMapping) || " + "@annotation(org.springframework.web.bind.annotation.PutMapping) || " + "@annotation(org.springframework.web.bind.annotation.DeleteMapping))")
5. 检查切面和控制器的Spring容器配置
- 确保你的切面类同时标注了
@Aspect和@Component,并且被Spring的组件扫描机制覆盖到; - 确保你的控制器类标注了
@Controller或@RestController,同样被Spring容器管理。
6. 检查Put方法是否无法被代理
如果你的Put方法是final或者static修饰的,Spring AOP(默认使用JDK动态代理或CGLIB)无法对这类方法生成代理,自然不会触发切面逻辑。
解决方法:去掉方法的final或static修饰符。
内容的提问来源于stack exchange,提问作者Laodao

