一,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.springframework.web.servlet.HandlerAdapter=
org.springframework.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了
三,HandlerAdapter
HandlerAdapter的作用:
之前一步,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
HttpRequestHandlerAdapter,
SimpleServletHandlerAdapter
SimpleControllerHandlerAdapter,
分别适配HttpRequest,Servlet,Controller类型的Handler
处理固定类型的Handler,内部调用固定方法进行处理
AnnotationMethodHandlerAdapter标记了@Deprecated已被弃用
用于适配注解类处理器,如经常使用的@Controller的这类处理器
HttpRequestHandlerAdapter的实现就非常复杂了
所处理的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);
}
适配实现了Servlet接口或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的整体流程
从DispatchServlet#onRefresh初始化九大组件,找到HandlerAdapter的初始化加载策略,即注册
DispatcherServlet#doService调用doDispatch方法,
看到HandlerAdapter在整个请求处理的过程中的作用和角色
HandlerAdapter接口定义和HandlerAdapter继承体系
介绍了除RequestMappingHandlerAdapter外的另外三种adapter的实现
下一节介绍HandlerAdapter的核心RequestMappingHandlerAdapter