一,HandlerAdapters 的初始化
DispatcherServlet-onRefresh 初始化 HandlerAdapters:
/** * This implementation calls {@link #initStrategies}. */@Overrideprotected void onRefresh(ApplicationContext context) { initStrategies(context);}
/*** Initialize the strategy objects that this servlet uses.* <p>May be overridden in subclasses in order to initialize further strategy objects.*/protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); // 初始化HandlerAdapters initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context);}
复制代码
initHandlerAdapters-初始化 HandlerAdapters:
/*** Initialize the HandlerAdapters used by this class.* <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,* we default to SimpleControllerHandlerAdapter.*/private void initHandlerAdapters(ApplicationContext context) { this.handlerAdapters = null;
// 加载所有实现了HandlerAdapter接口的bean if (this.detectAllHandlerAdapters) { // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts. Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values()); // We keep HandlerAdapters in sorted order. AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } // 只加载bean name="handlerAdapter"的handlerAdapter else { try { HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class); this.handlerAdapters = Collections.singletonList(ha); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerAdapter later. } }
// 如果仍未找到,从DispatcherServlet.properties加载默认配置 // Ensure we have at least some HandlerAdapters, by registering // default HandlerAdapters if no other adapters are found. if (this.handlerAdapters == null) { this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default"); } }}
复制代码
detectAllHandlerAdapters 属性-是否发现所有 HandlerAdapters:
1)默认为 true,加载当前系统中所有实现了 HandlerAdapter 接口的 bean 到 handlerAdapters
2)此属性可通过 web.xml 中 DispatcherServlet 的初始参数进行修改
<init-param> <param-name>detectAllHandlerAdapters</param-name> <param-value>false</param-value></init-param>
复制代码
detectAllHandlerAdapters 值为 false 时,只加载 bean name="handlerAdapter"的 handlerAdapter
3)加载不到的情况下将按照 DispatcherServlet.properties 中所定义的
org.springframework.web.servlet.HandlerAdapter 中的内容来加载缺省的 handlerAdapter。
DispatcherServlet.properties 配置文件-org.springframework.web.servlet.HandlerAdapter
org.springframewoDispatcherServlet#doService 调用了 doDispatch 方法work.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
复制代码
二,请求处理流程
DispatcherServlet#doService 调用了 doDispatch 方法:
/** * Process the actual dispatching to the handler. * <p>The handler will be obtained by applying the servlet's HandlerMappings in order. * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters * to find the first that supports the handler class. * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers * themselves to decide which methods are acceptable. * @param request current HTTP request * @param response current HTTP response * @throws Exception in case of any kind of processing failure */protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try { ModelAndView mv = null; Exception dispatchException = null;
try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; }
// 获取与处理器相匹配的handlerAdapter // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果是GET请求,如果内容没有变化的话,则直接返回 // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } }
// 调用执行器链中的拦截器,就是循环装配好的执行器链,执行 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }
// 执行handle // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) { return; } // 如果返回的ModelAndView不为null,并且没有设置view,设置默认的view。 applyDefaultViewName(processedRequest, mv); // 处理拦截器的postHandle。 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } // 如果出现异常,返回异常页面。 // 如果没有异常,ModelAndView不为null,则正常渲染页面,调用拦截器的afterCompletion方法 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } }}
复制代码
在 doDispatch 的整个流程中,涉及 HandlerAdapter 的有以下两处:
1,获取与处理器相匹配的 handlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
复制代码
getHandlerAdapter 的入参 mappedHandler:
HandlerExecutionChain mappedHandler = getHandler(processedRequest);// 根据request拿到HandlerExecutionChain对象// 包含一个处理器handler(如HandlerMethod对象),多个HandlerInterceptor拦截器对象
复制代码
getHandlerAdapter 源码:
/** * Return the HandlerAdapter for this handler object. * @param handler the handler object to find an adapter for * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error. */protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}
复制代码
遍历前面加载的 handlerAdapters(全部 handlerAdapter) 找出能够处理 handler 的 handlerAdapter:
备注:handlerAdapters 中包含多种实现了 handlerAdapters 接口的 handlerAdapter
supports 用于判断是否支持处理 handler,不同的 handlerAdapter 实现对不同 handler 的具体处理
2,执行 handle
ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// handle也是handlerAdapter接口的一个方法,用于HandlerAdapter的具体处理
复制代码
到这里前置的一些内容完成了,我们可以开始分析 HandlerAdapter 了
三,HandlerAdapterHandlerAdapter 的作用
之前一步,HandlerMapping,通过request找到对应的处理器Handler接下来在handlerAdapters找到可以处理该handler类型的handlerAdapterHandlerAdapter使用Handler对用户请求进行具体处理,最终返回ModelAndView
HandlerAdapter即适配器模式,用于统一不同handler的接口调用
复制代码
HandlerAdapter 接口:
package org.springframework.web.servlet;
public interface HandlerAdapter {
// 是否支持传入的Handler boolean supports(Object handler); // 使用Handler处理请求 ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
// 获取资源的LastModified值 long getLastModified(HttpServletRequest request, Object handler);
}
复制代码
四,HandlerAdapter 继承体系 HandlerAdapter 继承体系
从图中可以看出 HandlerAdapter 共有 5 类 Adapter:
SimpleServletHandlerAdapter,
SimpleControllerHandlerAdapter,
分别适配 HttpRequest,Servlet,Controller 类型的 Handler
处理固定类型的 Handler,内部调用固定方法进行处理;
用于适配注解类处理器,如经常使用的 @Controller 的这类处理器;
所处理的 Handler 可以是任意方法,参数的类型和数量也不确定
五,HttpRequestHandlerAdapter
适配处理器类型:
@Overridepublic boolean supports(Object handler) { return (handler instanceof HttpRequestHandler);}
复制代码
处理实现了 HttpRequestHandler 接口的处理器,
这类处理器的作用是处理通过 SpringMVC 来访问的静态资源的请求
处理逻辑:
@Override@Nullablepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response); return null;}
复制代码
直接调用 HttpRequestHandler#handleRequest,返回值为 null
通过改写 HttpServletResponse 实现前后端交互
六,SimpleServletHandlerAdapter
适配处理器类型:
@Overridepublic boolean supports(Object handler) { return (handler instanceof Servlet);}
复制代码
适配实现了 Servle t 接口或 Servlet 的子类的处理器,
可以在 web.xml 中配置 Servlet,也可以用 SpringMVC 来配置 Servlet,
此 HandlerAdapter 较少使用,默认加载的 handlerAdapters 中没有这个;
处理逻辑:
@Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
((Servlet) handler).service(request, response); return null;}
复制代码
调用 Servlet#service 对 handler 进行处理
七,SimpleControllerHandlerAdapter
适配处理器类型:
@Overridepublic boolean supports(Object handler) { return (handler instanceof Controller);}
复制代码
适配实现了 Controller 接口或 Controller 接口子类的处理器,
如:自己写的 Controller 继承自 MultiActionController,由 SimpleControllerHandlerAdapter 适配
处理逻辑:
@Override@Nullablepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response);}
复制代码
直接调用 Controller#handleRequest(具体实现类的 handleRequest 方法)
适配 SimpleUrlHandlerMapping 和 BeanNameUrlHandlerMapping 的映射;
八,结尾
这一节,主要介绍了关于 HandlerAdapter 的整体流程
DispatcherServlet#doService 调用 doDispatch 方法,看到 HandlerAdapter 在整个请求处理的过程中的作用和角色;
下一节,介绍 HandlerAdapter 的核心 RequestMappingHandlerAdapter;
评论