掘金 后端 ( ) • 2024-07-03 14:34

在这一章 SpringMVC原理(2)-目标方法是怎么被找到的 我们拿到了HandlerExecutionChain对象,也就是目标方法。那现在怎么执行目标方法呢?就需要一个处理器适配器来执行,所以现在需要找到目标方法合适的处理器适配器

我们是在@Controller标注的类中声明标注@xxxMapping注解的接口方法,所以拿到的HandlerExecutionChain对象中的Handler其实是HandlerMethod对象,也就是目标方法。所以下面我写Handler或目标方法都指的是一个意思。

getHandlerAdapter()

核心方法

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());:为处理器返回一个支持处理它的处理器适配器

 protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    if (this.handlerAdapters != null) {
       for (HandlerAdapter adapter : this.handlerAdapters) {
          if (adapter.supports(handler)) {
             return adapter;
          }
       }
    }
    throw new ServletException("No adapter for handler [" + handler +
          "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
 }

遍历所有的HandlerAdapter调用其supports()方法来判断当前处理器适配器是否支持处理此Handler

其实就是判断当前的这个Handler是不是某一个类。

image.png

我们这里RequestMappingHandlerAdapter就能处理,因为我们之前拿到的就是一个HandlerMethod

 // 我们默认在controller里声明的接口方法就是用的这个适配器来处理
 public final boolean supports(Object handler) {
     return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
 }
 
 protected boolean supportsInternal(HandlerMethod handlerMethod) {
     return true;
 }

至此我们就拿到了对应的HandlerAdapter,这一步还是比较简单的。后续就会通过HandlerAdapter来执行目标方法

总结

HandlerAdapter

image.png

HandlerAdapter

public interface HandlerAdapter {

   // 判断是否支持处理此Handler
   boolean supports(Object handler);

   // 调用目标方法来处理此请求
   @Nullable
   ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

   long getLastModified(HttpServletRequest request, Object handler);

}

RequestMappingHandlerAdapter

它专门用于处理带有@xxxMapping注解的控制器方法。(最常用)一个一个的接口方法会被封装为HandlerMethod对象

 public final boolean supports(Object handler) {
     return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
 }
 
 protected boolean supportsInternal(HandlerMethod handlerMethod) {
     return true;
 }

HttpRequestHandlerAdapter

用来处理实现了HttpRequestHandler接口的类。我们跨域的时候就用到了这个处理器适配器和这个HttpRequestHandler

SpringMVC原理(3)-跨域处理

 public boolean supports(Object handler) {
     return (handler instanceof HttpRequestHandler);
 }

SimpleControllerHandlerAdapter

用来处理实现了Controller接口的类。

 public boolean supports(Object handler) {
     return (handler instanceof Controller);
 }

HandlerFunctionAdapter

用来处理函数式编程风格的接口。

 public boolean supports(Object handler) {
     return handler instanceof HandlerFunction;
 }