spring-----mvc的反射调用
这几天在看spring mvc 源码,一直很好奇它究竟在哪进行的反射调用,通过源码,仔细阅读,最后发现了调用位置在类
InvocableHandlerMethod 的doInvoke 方法
/**
* Invoke the handler method with the given argument values.
*/
@Nullable
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
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);
}
}
} doInvoke又是在哪调用的呢?在同类的方法类
@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);
}
invokeForRequest 又是在哪里调用的呢?
在 ServletInvocableHandlerMethod 类的
/**
* Invoke the method and handle the return value through one of the
* configured {@link HandlerMethodReturnValueHandler HandlerMethodReturnValueHandlers}.
* @param webRequest the current request
* @param mavContainer the ModelAndViewContainer for this request
* @param providedArgs "given" arguments matched by type (not resolved)
*/
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()) {
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;
}
}
invokeAndHandle 是在哪里调用的?RequestMappingHandlerAdapter
/**
* 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 { ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
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);
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;
} return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
} 好了跟踪调用完毕。
spring-----mvc的反射调用的更多相关文章
- [LinqPad妙用]-在Net MVC中反射调用LinqPad中的Dump函数
LinqPad有个非常强大的Dump函数.这篇讲解一下如何将Dump函数应用在.Net MVC Web开发中. 先看效果: 一.用.Net Reflector反编译LinqPad.exe,找出Dump ...
- spring -mvc service层调用工具类配置
在service层时调用工具类时服务返回工具类对象为空 在此工具类上加上@Component注解就可以了 @Component:把普通pojo实例化到spring容器中,相当于配置文件中的 <b ...
- Spring MVC 通过反射将数据导出到excel
直接上代码 // 导出excel方法 @RequestMapping("exportExcel") public void exportExcel(HttpServletReque ...
- Spring MVC深入学习
一.MVC思想 MVC思想简介: MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范:MVC思想将一个应用部分分成三个基本部 ...
- Spring MVC 数据绑定流程分析
1. 数据绑定流程原理★ ① Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 Data ...
- Spring MVC 学习笔记(二)
6. 视图和视图解析器 ❤ Spring MVC如何解析视图 • 请求处理方法执行完成后,最终返回一个ModelAndView对象 ...
- Spring mvc数据转换 格式化 校验(转载)
原文地址:http://www.cnblogs.com/linyueshan/p/5908490.html 数据绑定流程 1. Spring MVC 主框架将 ServletRequest 对象及目标 ...
- [转载]快速搭建Spring MVC 4开发环境
(一)工作环境准备: JDK 1.7 Eclipse Kepler Apache Tomcat 8.0 (二)在Eclipse中新建Maven工程,在Archetype类型中,选择“maven-arc ...
- Spring MVC中jsessionid所引起的问题 和解决
转自:http://blog.csdn.net/seakingwy/article/details/1933687 jsessionid所引起的问题在Spring MVC当使用RedirectV ...
- Spring MVC 注解类型
Spring 2.5 引入了注解 基于注解的控制器的优势 1. 一个控制器类可以处理多个动作,而一个实现了 Controller 接口的控制器只能处理一个动作 2. 基于注解的控制器的请求映射不需要存 ...
随机推荐
- Python全栈工程师(字符串/序列)
ParisGabriel Python 入门基础 字符串:str用来记录文本信息字符串的表示方式:在非注释中凡是用引号括起来的部分都是字符串‘’ 单引号“” 双引号''' ''' ...
- diskimage-builder element
root阶段 创建或修改初始根文件系统内容. 这是添加替代分销支持的地方,还是建立在现有图像上的自定义. 只有一个元素可以一次使用它,除非特别注意不要盲目覆盖,而是适应其他元素提取的上下文. -cac ...
- Day2 Activity生命周期/启动模式/最佳实践
Android是使用任务(Task)来管理活动的,这个栈被称作返回栈(Back Stack). Activity类中定义了7个回调方法: onCreate().在活动第一次被创建时调用,应该在这个方法 ...
- Android 启动项 Activity
使用SDK创建一个App的时候,基本都会看到这段代码: <activity android:name=".ExampleActivity" android:icon=&quo ...
- Numpy 与 DataFrame对比与应用
(一)对比Numpty 与 DataFrame默认索引取值不同点 Numpy索引取值 #Numpy索引取值 data=np.empty((2,4),dtype=int) print(data) ''' ...
- 第二阶段团队冲刺-two
昨天: 处理第一次启动服务器500的问题. 今天: 修复博客作业查询功能. 遇到的问题: 无.
- 移动平台自动化测试:appium(一)
Appium 是一个开源的,跨平台的自动化测试工具.它支持模拟器(iOS,FirefoxOS,Android)和真机(iOS, Android, FirefoxOS)上的原生应用,混合应用和移动 we ...
- (总结)Nginx 502 Bad Gateway错误触发条件与解决方法
一些运行在Nginx上的网站有时候会出现“502 Bad Gateway”错误,有些时候甚至频繁的出现.以下是从Google搜集整理的一些Nginx 502错误的排查方法,供参考: Nginx 502 ...
- [codeforces] 526D [51nod] 1554 欧姆诺姆和项链
原题 KMP 方法一: 听说是ex-kmp--来自学姐 ex-kmp是处理两个串s和t之间,t的每一个后缀在s中的最长前缀的长度的一个算法. 它很像manacher(至少我和学姐这么认为),记录了一个 ...
- Linux系统——C/C++开发工具及环境搭建
首先,我们是要在Linux下进行项目开发,让我们把windows“拆了”,装个Linux也是不可能的,会带来很多的不便,所以我们首先需要在虚拟机上安装Linux操作系统,我本次用的是CentOS,它也 ...