交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
springmvc第4- 1章:ServletInvocableHandlerMethod
分享
未结
0
909
李延
LV6
2021-05-26
悬赏:20积分
# 作用 在HandlerAdapter中,我们准备了所有的组件,都传给了ServletInvocableHandlerMethod这个类: 而我们mvc最核心的处理逻辑也在这个类中实现,包括:参数绑定、方法执行、返回回值处理。都在这个类中解决 # 继承关系  我们看到它的顶级父类就是HandlerMethod。而HandlerMethod就是我们之前一直使用的Handler,其中里面封装的就是我们真正的方法。 ## 主要方法 直接看HandlerAdapter里调用的invokeAndHandle方法 ```java 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; } } ``` 其中这里主要就2步: - 调用父类方法invokeForRequest,进行参数绑定与方法执行 - 调用returnValueHandlers的handleReturnValue,进行返回值处理 对于返回值的HandlerMethodReturnValueHandlerComposite对象。就是在HandlerAdapter中初始化方法中初始化的对象。我们在单独详细说明 我们跟进父类的invokeForRequest方法: ```java @Nullable public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Arguments: " + Arrays.toString(args)); } return doInvoke(args); } ``` 这里主要有2步: - 调用getMethodArgumentValues绑定参数 - 调用doInvoke 调用方法 其中doInvoke就是通过反射调用我们的方法。不在详细说明。我们主要看getMethodArgumentValues方法 ```java protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { MethodParameter[] parameters = getMethodParameters(); if (ObjectUtils.isEmpty(parameters)) { return EMPTY_ARGS; } Object[] args = new Object[parameters.length]; for (int i = 0; i < parameters.length; i++) { MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); args[i] = findProvidedArgument(parameter, providedArgs); if (args[i] != null) { continue; } if (!this.resolvers.supportsParameter(parameter)) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } try { args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception ex) { // Leave stack trace for later, exception may actually be resolved and handled... if (logger.isDebugEnabled()) { String exMsg = ex.getMessage(); if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { logger.debug(formatArgumentError(parameter, exMsg)); } } throw ex; } } return args; } ``` 这里我们看到所有的处理过程都是调用resolvers来完成的,首先通过supportsParameter判断当前参数是否可以解析,不能解析报错。可以解析则调用resolveArgument方法进行解析。 具体过程在HandlerMethodArgumentResolver中说明。
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号