SpringMvc源码-RequestMappingHandlerAdapter

HandlerAdapter接口的说明

在SprintMVC中,HandlerAdapter组件是一个handler适配器类,它通过handle方法调用request对应的controller方法来处理请求【HandlerMethod】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 /**
* Use the given handler to handle this request.
* The workflow that is required may vary widely.
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler to use. This object must have previously been passed
* to the {@code supports} method of this interface, which must have 实际上是 HandlerMethod
* returned {@code true}.
* @throws Exception in case of errors
* @return a ModelAndView object with the name of the view and the required
* model data, or {@code null} if the request has been handled directly
*/
//
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

如何获取HandlerAdapter

见DispatcherServlet.getHandlerAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
//遍历DipatcherServlet.properties里org.springframework.web.servlet.HandlerAdapter的配置,调用handlerAdpater.supports看那个符合条件
//Springboot中,会执行RequestMappingHandler.supports-->AbstractHandlerMethodAdapter.supports 即handler是HandlerMetod
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");
}

handle方法的执行

调用路径是AbstractHandlerMethodAdapter.handle()–>AbstractHandlerMethodAdapter.handleInternal()–>RequestMappingHandlerAdapter.handleInternal。

见RequestMappingHandlerAdapter.handleInternal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ModelAndView mav;
//校验requestMethod和requireSession
checkRequest(request);

// Execute invokeHandlerMethod in synchronized block if required.
// session线程不安全,如果想用户多次请求都访问同一个session需要加一个全局锁。。性能极差很少见
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No synchronization on session demanded at all...
// 关键方法,代理方法执行handlerMethod,返回modelAndView
mav = invokeHandlerMethod(request, response, handlerMethod);
}

if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}

return mav;
}

controller方法的执行原理,代理模式和反射的应用:invokeHandlerMethod

最终的执行实际上是利用了java的反射包,以及代理模式,关键代码见:invokeHandlerMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
* if view resolution is required.
* @since 4.2
* @see #createInvocableHandlerMethod(HandlerMethod)
*/
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//HttpServletRequest 的封装
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//用来处理request中的参数映射,WebDataBinderFactory里的值见:afterPropertiesSet
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//用来创建初始化model
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
//根据handlerMethod实例化一个ServletInvocableHandlerMethod来处理请求
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
//设置argumentResolvers处理request的参数 argumentResolvers里的值见afterPropertiesSet
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
//设置argumentResolvers处理response的参数 returnValueHandlers里的值见afterPropertiesSet
// 可自定义 TODO 比如想给所有的ResponseBody返回值封装成{code:0,msg:1,data:null}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

//modelAndView的上下文对象
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
//初始化Model对象,同时将sessionAtrributes值和ModelAtrributes的值都合并在一起放在Model中
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

//todo 未读
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);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}

//关键代码,通过handlerMethod的代理方法,执行Controller的方法,将结果存储到mavContainer
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}

//获取ModelAndView
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}

invocableMethod.invokeAndHandle(webRequest, mavContainer);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {

//关键代码,通过java的反射机制doInvoke执行handlerMethod对应的controller方法
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);

if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}

mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
//调用returnValueHandlers 将返回值写到response中(webRequest.getNativeResponse)里
// 由于现在开发采用前后端分离,RestApi往往会用到RequestResponseBodyMethodProcessor,可以看这个类,返回值和controller方法有@ResponseBody
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}

invokeForRequest方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//从request里获取controller执行方法的参数,request里的值变为方法里设置的参数
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
//通过java的反射机制,执行controller里的方法,方法参数getMethodArgumentValues获取
return doInvoke(args);
}

protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
//todo 通过反射执行方法 书签
//调用java反射包的invoke 代理执行HandlerMethod里econtroller对应的方法
// getBridgedMethod= 如果没有意外等于controller被执行的方法
// getBean()=Controller对象
// args=request通过argumentResolver得到的方法参数对象
return getBridgedMethod().invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
assertTargetBean(getBridgedMethod(), getBean(), args);
String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
throw new IllegalStateException(formatInvokeError(text, args), ex);
}
catch (InvocationTargetException ex) {
// Unwrap for HandlerExceptionResolvers ...
Throwable targetException = ex.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(formatInvokeError("Invocation failure", args), targetException);
}
}
}