代码:

handler instanceof HandlerMethod

是用于判断当前请求是否由一个具体的控制器方法(Controller Method)来处理。为了更清楚地解释它为什么能“判断”,我们先从 Spring MVC 的请求处理机制谈起。


🌐 1. Spring MVC 中的请求处理流程

在 Spring MVC 中,每个 HTTP 请求最终都会被映射到一个“处理器”(Handler)。这个“处理器”可以是以下几种形式:

  • 一个实现了 Controller 接口的类(旧式写法)
  • 一个带有 @RequestMapping 注解的方法(现代常用方式),Spring 会将它封装为 HandlerMethod
  • 一个 HttpRequestHandler(用于静态资源等)

所以,handler 是一个通用的 Object 类型对象,Spring 并不能一开始就确定它是哪种类型。


✅ 2. 为什么要用 instanceof HandlerMethod 判断?

原因:只有 HandlerMethod 才代表一个具体的方法

如果你要对某个 Controller 方法做拦截(比如权限检查、日志记录等),你就必须确保这个 handler 是一个方法级别的处理器(即 HandlerMethod),而不是一个类级别或其他类型的处理器。

举个例子:

// UserController.java
@GetMapping("/user/login")
public Result login() {
    return Result.success();
}

上面的 /user/login 接口会被 Spring 封装为一个 HandlerMethod,表示调用的是 UserController.login() 这个方法。

而如果你不加 if (handler instanceof HandlerMethod) 判断,就可能会遇到如下问题:

if (handler.getClass() == HandlerMethod.class) { /* 错误写法 */ }

这种方式不如 instanceof 安全,因为子类无法匹配。使用 instanceof 更加稳妥。


🔍 3. 举个实际场景说明它的作用

假设你正在编写一个 VIP 权限拦截器:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (handler instanceof HandlerMethod) {
        HandlerMethod hm = (HandlerMethod) handler;
        if (hm.getMethod().isAnnotationPresent(VipRequired.class)) {
            // 如果该方法需要 VIP 权限,则进一步判断用户是否是 VIP
            if (!isUserVip(request)) {
                throw new VipRequiredException();
            }
        }
    }
    return true;
}

这段逻辑中:

  • 首先判断 handler 是否是 HandlerMethod 类型;
  • 如果是,才去获取方法上的注解 @VipRequired
  • 然后根据是否有这个注解进行 VIP 权限校验。

如果跳过 instanceof 判断,直接强制转换成 HandlerMethod,会导致运行时错误(ClassCastException)。


🧠 总结:为什么能判断?

表达式 含义
handler instanceof HandlerMethod 检查当前请求的目标是否是一个具体的方法(而非类或其它处理器)
为什么能判断? 因为 Spring 在处理请求时,会根据请求路径找到对应的处理器(handler),这个 handler 可以是多种类型,而 HandlerMethod 是专门用来封装 Controller 方法的类。通过 instanceof,我们可以准确判断当前 handler 是否是我们想要操作的对象。

💡 类比理解:

你可以把它想象成这样的场景:

你走进一家餐厅,服务员问你:“你是来吃饭的吗?”
如果你说“是”,那他才会继续问你要点什么菜;
如果你说“不是”,比如你是来开会的,那他就不会让你点菜了。

同理,handler instanceof HandlerMethod 就是在问:“这个请求是不是要执行一个具体的方法?”
如果是,就继续处理;如果不是,就跳过。