一,HandlerAdapters 的初始化
DispatcherServlet-onRefresh 初始化 HandlerAdapters:
/**
* This implementation calls {@link #initStrategies}.
*/
@Override
protected 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类型的handlerAdapter
HandlerAdapter使用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
适配处理器类型:
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
复制代码
处理实现了 HttpRequestHandler 接口的处理器,
这类处理器的作用是处理通过 SpringMVC 来访问的静态资源的请求
处理逻辑:
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object handler)throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
复制代码
直接调用 HttpRequestHandler#handleRequest,返回值为 null
通过改写 HttpServletResponse 实现前后端交互
六,SimpleServletHandlerAdapter
适配处理器类型:
@Override
public boolean supports(Object handler) {
return (handler instanceof Servlet);
}
复制代码
适配实现了 Servle t 接口或 Servlet 的子类的处理器,
可以在 web.xml 中配置 Servlet,也可以用 SpringMVC 来配置 Servlet,
此 HandlerAdapter 较少使用,默认加载的 handlerAdapters 中没有这个;
处理逻辑:
@Override
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object handler)throws Exception {
((Servlet) handler).service(request, response);
return null;
}
复制代码
调用 Servlet#service 对 handler 进行处理
七,SimpleControllerHandlerAdapter
适配处理器类型:
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
复制代码
适配实现了 Controller 接口或 Controller 接口子类的处理器,
如:自己写的 Controller 继承自 MultiActionController,由 SimpleControllerHandlerAdapter 适配
处理逻辑:
@Override
@Nullable
public 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;
评论