访问控制符导致 Spring 映射失效

相关概念:spring-boot

在 Spring MVC 里,@RequestMapping 一类注解标在方法上,不代表这个方法就一定能正常作为 Handler 工作。

有时候问题不是注解没写对,而是方法的可见性不对。

现象

同一个 Controller 里:

  • public 方法映射正常
  • private 方法看起来也写了 @PutMapping
  • 但请求打过去就是不符合预期,或者根本没有按框架预期的方式被处理

像这样:

@PostMapping("/product/{id}")
public Object decreaseStock(@PathVariable String id) {
    return stock;
}
 
@PutMapping("/product/{id}")
private Object decreaseStock2(@PathVariable String id) {
    return stock;
}

核心点

Spring 这类基于反射、代理和框架约定工作的机制,对方法可见性是有要求的。

private 方法天然就不适合放在这类需要被框架发现、调用、增强的位置上。

所以这类问题的结论很简单:

作为 Controller Handler、切面切点目标、事务入口的方法,优先保持 public

原因

因为从 Java 语法上看,private 方法完全合法,IDE 也不会自动提示这已经越过了框架约定的边界。

但从框架语义上看,这类方法往往已经越过了“框架能正常接管”的边界。

心得

遇到 Spring 里“注解明明写了,但行为不对”时,可以先检查这几件事:

  • 方法是不是 public
  • 类和方法是不是被 Spring 容器真正管理
  • 调用是不是绕开了代理

比起一开始怀疑版本或配置,这几个点通常更值得先过一遍。