HandlerInterceptor 有一个 Object 处理程序参数,哪些类型将传递给拦截器?

HandlerInterceptor has an Object hander parameter, what types will get passed into the interceptor?

HandlerInterceptor接口有一个参数Object handler,这意味着实现代码必须对处理程序对象进行类型检查才能使用它,并根据需要对其进行转换。

我发现的代码片段似乎假定处理程序始终是一个 HandlerMethod 对象,如果不是这种情况,则 return 为真,但我想了解为什么这似乎是一个通用的实现来实现一个健壮的实现。

实现此接口的标准方法似乎是:

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            // ...
            return x; // whether or not to proceed with execution
        }
        return true; // fallback value in case handler wasn't a HandlerMethod
    }
}

Spring javadoc 似乎忽略了接口中有 Object 类型这一事实,这对我理解这个接口非常无益。

一些可能有助于我理解该接口应该如何实现的问题:

HandlerInterceptor#preHandle() 的 javadoc 是这样说的:

Interception point before the execution of a handler. Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler.
DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can decide to abort the execution chain, typically sending an HTTP error or writing a custom response.

这意味着拦截器根本不应该接触 handler,因此他们不需要知道任何相关信息。他们唯一的工作就是决定是否进一步通过请求。

顺便说一句,org.springframework.web.servlet.* 中的标准 HandlerInterceptor#preHandle() 实现的 none 尝试分析真正的 handler 参数类型并根据它执行任何逻辑。

Why is it an Object, not a HandlerMethod, parameter?

来自 org.springframework.web.servlet.HandlerMapping#getHandler() javadoc:

Return a handler and any interceptors for this request. The choice may be made on request URL, session state, or any factor the implementing class chooses.
The returned HandlerExecutionChain contains a handler Object, rather than even a tag interface, so that handlers are not constrained in any way. For example, a HandlerAdapter could be written to allow another framework's handler objects to be used.

基本上,handler 参数可以是存在 HandlerAdapter 的任何类型。最常用的是 RequestMappingHandlerAdapter 利用 HandlerMethod.

但它可以是一个常规 class、一个 servlet,甚至是一个函数(当使用函数式方法时)。 Spring Web 服务也有一个实现以及 Spring 集成。

Spring本身会支持下面的out-of-the-box

所以不,它并不总是 HandlerMethod 但它适用于大多数用户。