0%

HandlerAdapter

HandlerAdapter

介绍

HandlerAdapterHandler的适配器,每种类型的Handler都对应一个HandlerAdapter

分析

在顶层接口HandlerAdapter的实现中,基本上都是直接具体的实现。

HandlerAdapter类图png.png

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
public interface HandlerAdapter {

/**
* 当前 HandlerAdapter 是否支持这个 Handler
*
* @param handler the handler object to check
* @return whether or not this object can use the given handler
*/
boolean supports(Object handler);

/**
* 利用 Handler 处理请求
*
* @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;

/**
*/
long getLastModified(HttpServletRequest request, Object handler);

}

这里以AbstractHandlerMethodAdapter为例进行分析。这个抽象类也比较简答,仅仅是将顶层接口中的参数进行具象化,再调用本类的模板方法,供子类直接使用,所以子类就不需要在进行类型装换等操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public final boolean supports(Object handler) {
// 如果handler是HandlerMethod, 直接强转后调用模板方法
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}

protected abstract boolean supportsInternal(HandlerMethod handlerMethod);


@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 仅仅是强转了类型之后, 直接调用模板方法
return handleInternal(request, response, (HandlerMethod) handler);
}


@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;

具体实现RequestMappingHandlerAdapter

RequestMappingHandlerAdapterHandlerAdapter体系中最复杂的类,包含了具体Handler执行前后需要特殊处理或者是一些开放的扩展点的处理。比如有参数处理器、参数名称处理器、HttpMessageConverter、结果处理器等等。

1.初始化

RequestMappingHandlerAdapter的初始化分为两步,一步是在构造函数中进行默认HttpMessageConvert的添加,另一步是通过afterPropertiesSet进行一些全局处理的缓存和一些组件的初始化。

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
72
73
74
75
76
77
78
79
80
81
public RequestMappingHandlerAdapter() {
this.messageConverters = new ArrayList<>(4);
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
try {
this.messageConverters.add(new SourceHttpMessageConverter<>());
}catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
}

@Override
public void afterPropertiesSet() {
//初始化全局的三个变量modelAttributeAdviceCache、initBinderAdviceCache、requestResponseBodyAdvice
initControllerAdviceCache();

//初始化参数解析器argumentResolvers参数
if (this.argumentResolvers == null) {
// getDefaultArgumentResolvers()中定义了一些常用的参数解析器,同时支持添加用户自定义参数解析器
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}

//初始化initBinder式参数绑定器initBinderArgumentResolvers
if (this.initBinderArgumentResolvers == null) {
// 通过getDefaultInitBinderArgumentResolvers()获取默认的解析器,同时支持添加用户自定义参数绑定器
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}

//初始化返回值处理器returnValueHandlers
if (this.returnValueHandlers == null) {
// 通过getDefaultReturnValueHandlers()方法获取返回值解析器,同时支持添加用户自定义返回值处理器
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}

/**
* 初始化全局的三个变量modelAttributeAdviceCache、initBinderAdviceCache、requestResponseBodyAdvice
*
* @Author: xiaocainiaoya
* @Date: 2021/08/18 10:12:25
**/
private void initControllerAdviceCache() {
if (getApplicationContext() == null) {
return;
}
// 获取带有@ControllerAdvice的所有类
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();

for (ControllerAdviceBean adviceBean : adviceBeans) {
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
}
// 存在@ModelAttribute注解, 但不存在@RequestMapping注解的方法
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
}
// 存在@InitBinder注解的方法
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(adviceBean, binderMethods);
}
// 是RequestBodyAdvice或者是ResponseBodyAdvice的实现类
if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
requestResponseBodyAdviceBeans.add(adviceBean);
}
}

// 若在上述解析过程中存在实现类, 则添加到最前面, 所以在requestResponseBodyAdvice中, 自定义的优先级高于默认
if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
}

2.实际处理

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@Override
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ModelAndView mav;
//判断是否支持当前request的方法,该方法在WebContentGenerator类中定义,通过内置的supportedMethods属性来进行判断
checkRequest(request);

// Execute invokeHandlerMethod in synchronized block if required.
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...
mav = invokeHandlerMethod(request, response, handlerMethod);
}

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

@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
// 获取创建WebDataBinder实例的工厂类,其中WebDataBinder类用于绑定request参数到JavaBean对象
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
// 获取@ModelAttribute的非@RequestMapping方法
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// ServletInvocableHandlerMethod是继承于HandlerMethod, 这里相当于只是将handlerMethod中的属性值赋值给invocableMethod, 仅仅只做了包了一层
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
// 为ServletInvocableHandlerMethod中的一些数据赋值, 增加了参数解析、处理器方法调用、返回值解析等逻辑
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();
// 设置FlashMap中的值
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);
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);
}

// 具体的执行方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
// 若是异步方式, 这里就直接返回了
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
//构建ModelAndView实例
return getModelAndView(mavContainer, modelFactory, webRequest);
}finally {
webRequest.requestCompleted();
}
}

ServletInvocableHandlerMethod就是具体的HandlerMethod的实现,所以在最后通过invocableMethod.invokeAndHandle(webRequest, mavContainer)调用到具体的实现。以下基本上就是具体Handler的调用前最后一步了,返回执行结果之后,由结果处理器进行处理。

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
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
// 执行调用逻辑(这里会先经过参数解析器的处理之后,再通过反射调用到具体的方法)
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 {
// 返回值处理器处理
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}

这里想简要说明一下异步调用的场景:Servlet3.0支持服务器异步操作,在springmvc中也添加了响应的支持。整个请求的过程与同步类似,只是在具体的handler调用之后,如果是异步方式,假设是使用Callable,则这里获取到的返回值处理器就是CallableMethodReturnValueHandler

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
Callable<?> callable = (Callable<?>) returnValue;
// 进入Callable方式异步处理逻辑
WebAsyncUtils.getAsyncManager(webRequest).startCallableProcessing(callable, mavContainer);
}

public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object... processingContext) throws Exception {
Assert.notNull(webAsyncTask, "WebAsyncTask must not be null");
Assert.state(this.asyncWebRequest != null, "AsyncWebRequest must not be null");

// 设置超时时间
Long timeout = webAsyncTask.getTimeout();
if (timeout != null) {
this.asyncWebRequest.setTimeout(timeout);
}

/**
* 设置异步线程池
* 1. 默认情况下会创建DEFAULT_TASK_EXECUTOR -> SimpleAsyncTaskExecutor线程池
* 2. 一般来说, 在RequestMappingHandlerAdapter中, 创建的WebAsyncManager时会传入它的this.taskExecutor
* 2.1 而RequestMappingHandlerAdapter也会创建一个默认的SimpleAsyncTaskExecutor(名称前缀为MvcAsync)
* 2.1.1 但是在springmvc中, 初始化Bean RequestMappingHandlerAdapter时为它添加了单一线程池Executor.newSingleThreadExecutor
* 2.1.2 但是在springboot中, 初始化Bean RequestMappingHandlerAdapter时为它添加了一个名为applicationTaskExecutor的线程池
*/
AsyncTaskExecutor executor = webAsyncTask.getExecutor();
if (executor != null) {
this.taskExecutor = executor;
}else {
logExecutorWarning();
}
// 设置拦截器
List<CallableProcessingInterceptor> interceptors = new ArrayList<>();
interceptors.add(webAsyncTask.getInterceptor());
interceptors.addAll(this.callableInterceptors.values());
interceptors.add(timeoutCallableInterceptor);

// 获取具体的callable
final Callable<?> callable = webAsyncTask.getCallable();
// 创建拦截器链对象, 拦截器链对象一般情况下都会包含拦截列表、具体执行对象以及具体执行到某个拦截器的下标值
final CallableInterceptorChain interceptorChain = new CallableInterceptorChain(interceptors);

// 设置超时处理器
this.asyncWebRequest.addTimeoutHandler(() -> {
if (logger.isDebugEnabled()) {
logger.debug("Async request timeout for " + formatRequestUri());
}
Object result = interceptorChain.triggerAfterTimeout(this.asyncWebRequest, callable);
if (result != CallableProcessingInterceptor.RESULT_NONE) {
setConcurrentResultAndDispatch(result);
}
});
// 设置错误处理器
this.asyncWebRequest.addErrorHandler(ex -> {
if (!this.errorHandlingInProgress) {
if (logger.isDebugEnabled()) {
logger.debug("Async request error for " + formatRequestUri() + ": " + ex);
}
Object result = interceptorChain.triggerAfterError(this.asyncWebRequest, callable, ex);
result = (result != CallableProcessingInterceptor.RESULT_NONE ? result : ex);
setConcurrentResultAndDispatch(result);
}
});
// 设置正常完成处理器
this.asyncWebRequest.addCompletionHandler(() -> interceptorChain.triggerAfterCompletion(this.asyncWebRequest, callable));

interceptorChain.applyBeforeConcurrentHandling(this.asyncWebRequest, callable);
// 设置一些标志位为启动状态
startAsyncProcessing(processingContext);
try {
// 将callable丢入线程池中
Future<?> future = this.taskExecutor.submit(() -> {
Object result = null;
try {
interceptorChain.applyPreProcess(this.asyncWebRequest, callable);
result = callable.call();
}catch (Throwable ex) {
result = ex;
}finally {
result = interceptorChain.applyPostProcess(this.asyncWebRequest, callable, result);
}
// 执行完成之后进行结果的分发, 这个具体在不同容器有不同的实现(tomcat、undertow)
setConcurrentResultAndDispatch(result);
});
interceptorChain.setTaskFuture(future);
}catch (RejectedExecutionException ex) {
Object result = interceptorChain.applyPostProcess(this.asyncWebRequest, callable, ex);
setConcurrentResultAndDispatch(result);
throw ex;
}
}

-------------本文结束感谢您的阅读-------------