接口
public interface HandlerAdapter {
/**
* 是否能处理指定Handler
* @param var1
* @return
*/
boolean supports(Object var1);
/**
* 处理Handler
* @param var1
* @param var2
* @param var3
* @return
* @throws Exception
*/
@Nullable
ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
/**
* 获取资源最后一次更新时间
* @param var1
* @param var2
* @return
*/
long getLastModified(HttpServletRequest var1, Object var2);
}
类图

我们回到Dispatcher开始看起
DispatcherServlet
doDispatch
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//获取异步管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
/**
* 如果配置了MultipartResolver 会调用 isMultipart() 方法判断请求中是否包含文件。
* 如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart()
* 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile
* 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中并返回
*/
processedRequest = this.checkMultipart(request);
//是否被解析
multipartRequestParsed = processedRequest != request;
//通过HandlerMapping获得 HandlerExecutionChanin如:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMappin
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
//没获取到抛出404异常
this.noHandlerFound(processedRequest, response);
return;
}
//<1>返回对应能处理的HandlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (this.logger.isDebugEnabled()) {
this.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;
}
//<3>真正的处理方法 返回视图 没有视图则返回null
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//是否开启异步管理器
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//设置默认的viewName
this.applyDefaultViewName(processedRequest, mv);
//后置处理 拦截器
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var19) {
dispatchException = var19;
}
//处理正常和异常的请求调用结果。
this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
} catch (Exception var20) {
//触发异常拦截器的AfterCompletion实现
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
} catch (Error var21) {
//触发异常拦截器的AfterCompletion实现
this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
<1>getHandlerAdapter
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
//<2>遍历所有适配器 传入handler 判断判断adapter是否能处理
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");
}
RequestMappingHandlerAdapter
<2>supports
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
public final boolean supports(Object handler) {
//判断Handler是否是HandlerMethod 类型 supportsInternal是个抽象方法由子类实现 也就是RequestMappingHandlerAdapter
return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
}
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#supportsInternal
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
<3>handle
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//<4>调用子类的实现 抽象方法模板方法实现
return this.handleInternal(request, response, (HandlerMethod)handler);
}
<4>handleInternal
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//<5>检查是否配置了只能处理请求 以及是否必须存在session而没有传
this.checkRequest(request);
ModelAndView mav;
//是否有配置根据session加锁
if (this.synchronizeOnSession) {
//true为如果不存在session则创建一个并返回 false不存在直接返回null
HttpSession session = request.getSession(false);
if (session != null) {
/**
* Object mutex = session.getAttribute(SESSION_MUTEX_ATTRIBUTE);
* 如果为空则返回当前session对象 当我们有需求保证一个session原子性的时候用吧 就一个加同步锁动作
*/
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) {
//<6>执行处理返回modelView
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
//<6>执行处理返回modelView
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
//<6>执行处理求返回modelView
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
/**
* 响应头Cache-Control是通知浏览器缓存
* 这里主要是@SessionAttribute用法的处理
* 很少用到 也可兼容https://blog.csdn.net/qq_38737992/article/details/89763067 处理
*/
if (!response.containsHeader("Cache-Control")) {
if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
this.prepareResponse(response);
}
}
return mav;
}
<5>checkRequest
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.support.WebContentGenerator#checkRequest
protected final void checkRequest(HttpServletRequest request) throws ServletException {
//获得请求方式
String method = request.getMethod();
//判断是否支持 我们可以通过这个支持的请求方式
if (this.supportedMethods != null && !this.supportedMethods.contains(method)) {
throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods);
//判断是否配置了必须存在session
} else if (this.requireSession && request.getSession(false) == null) {
throw new HttpSessionRequiredException("Pre-existing session required but none found");
}
}
<6>invokeHandlerMethod
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndView var15;
try {
WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
//交给ServletInvocableHandlerMethod 对象代理handlerMethod
ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
//入参绑定器 set 后续使用
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
//方绘制绑定器
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
//异步超时时间
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
//设置线程池
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
//拦截器
asyncManager.registerCallableInterceptors(this.callableInterceptors);
//DeferredResult方式拦截器
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
Object result;
/**
* 主要针对我们返回值是Callable 会释放Dispatcher占用的线程 交给的taskExecutor之心你那个 但是与客户端连接还保持
* 当拿回结果 从新走Dispatcher入口进来 这里判断就会是true
*/
if (asyncManager.hasConcurrentResult()) {
result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
//同时这类替换invocableMethod为ServletInvocableHandlerMethod.ConcurrentResultHandlerMethod 继承ServletInvocableHandlerMethod
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//<7>执行后续请求处理
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
if (asyncManager.isConcurrentHandlingStarted()) {
result = null;
return (ModelAndView)result;
}
//<如果我们返回ModelAndView则会被ModelAndViewMethodReturnValueHandler 封装到 mavContainenr 这里则根据MavContainer获取
var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
} finally {
webRequest.requestCompleted();
}
return var15;
}
ServletInvocableHandlerMethod
<7>invokeAndHandle
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
->
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//<7_1>执行参数绑定 执行控制器方法取回返回结果
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);
this.setResponseStatus(webRequest);
if (returnValue == null) {
if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) {
mavContainer.setRequestHandled(true);
return;
}
} else if (StringUtils.hasText(this.getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
//必须返回值处理器
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
//<10>通过返回值处理器进行返回值处理
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);
} catch (Exception var6) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(this.formatErrorForReturnValue(returnValue), var6);
}
throw var6;
}
}
<7_1>invokeForRequest
org.springframework.web.servlet.FrameworkServlet#service
->
org.springframework.web.servlet.FrameworkServlet#processRequest
->
org.springframework.web.servlet.DispatcherServlet#doService
->
org.springframework.web.servlet.DispatcherServlet#doDispatch
->
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
->
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
->
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
->
org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//<8>通过绑定器绑定参数
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Arguments: " + Arrays.toString(args));
}
//<9>调用对应的controller方法
return this.doInvoke(args);
}
<8>getMethodArgumentValues
org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//获得对应的绑定参数
MethodParameter[] parameters = this.getMethodParameters();
Object[] args = new Object[parameters.length];
for(int i = 0; i < parameters.length; ++i) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
//这里是优先获取 @Init方法注册的合适的绑定器 返回的类型绑定器
args[i] = this.resolveProvidedArgument(parameter, providedArgs);
if (args[i] == null) {
//遍历所有参数绑定器找到合适的绑定器
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
//解析出参数
args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
} catch (Exception var10) {
if (this.logger.isDebugEnabled()) {
String message = var10.getMessage();
if (message != null && !message.contains(parameter.getExecutable().toGenericString())) {
this.logger.debug(formatArgumentError(parameter, message));
}
}
throw var10;
}
} else if (args[i] == null) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
}
}
//返回参数
return args;
}
<9>doInvoke
org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(this.getBridgedMethod());
try {
//反射调用对应的Method方法
return this.getBridgedMethod().invoke(this.getBean(), args);
} catch (IllegalArgumentException var4) {
this.assertTargetBean(this.getBridgedMethod(), this.getBean(), args);
String text = var4.getMessage() != null ? var4.getMessage() : "Illegal argument";
throw new IllegalStateException(this.formatInvokeError(text, args), var4);
} catch (InvocationTargetException var5) {
Throwable targetException = var5.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException)targetException;
} else if (targetException instanceof Error) {
throw (Error)targetException;
} else if (targetException instanceof Exception) {
throw (Exception)targetException;
} else {
throw new IllegalStateException(this.formatInvokeError("Invocation failure", args), targetException);
}
}
}
<10>handleReturnValue
org.springframework.web.method.support.InvocableHandlerMethod#handleReturnValue
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
//<11>根据响应值和响应参数选取合适的BindType
HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType);
if (handler == null) {
throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
} else {
//写入body 我们可以自定义绑定在写入之前执行一些逻辑
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
}
<11>selectHandler
org.springframework.web.method.support.InvocableHandlerMethod#selectHandler
@Nullable
private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
boolean isAsyncValue = this.isAsyncReturnValue(value, returnType);
Iterator var4 = this.returnValueHandlers.iterator();
HandlerMethodReturnValueHandler handler;
do {
do {
if (!var4.hasNext()) {
return null;
}
handler = (HandlerMethodReturnValueHandler)var4.next();
} while(isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler));
//返回supportsReturnType 调用判断是否能处理
} while(!handler.supportsReturnType(returnType));
return handler;
}
如:RequestBody绑定器的实现
public boolean supportsReturnType(MethodParameter returnType) {
return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);
}
总结
1.RequestMappingHandlerAdapter最终内部会将请求委托给ServletInvocableHandlerMethod处理
2.ServletInvocableHandlerMethod 会先经过参数绑定器获得参数args数组
3.然后通能反射调用Controller的对应方法
4.再通过响应绑定器对不同的响应内容做处理 比如解析@ResponseBody的响应处理器
来源:https://www.cnblogs.com/LQBlog/p/12222381.html