一直对springmvc源码感兴趣,就看了下源码,写下这偏文章,当做笔记
springmvc主要是完成逻辑方法的映射和参数绑定工作,它的初始化是随着Tomcat启动时,调用HttpServlet进行。
通过DispatcherServlet会创建一个XmlWebApplicationContext,然后进行Controller等Bena的扫描和实例化,然后
调用容器的refresh方法进行九大部件的注册
下面贴下流程图:
1.Tomcat启动后,DisparcherServlet的初始化流程
2.RequestMappingHandlerMapping的初始化流程和作用:
它是在实例化后进行映射方法的扫描和注册,然后封装了RequestMappingInfo和MethodHandler方法的映射Map中缓存。RequestMappingInfo的信息一般是对@RequestMapping注解的解析,MethodHandler包含Controller方法的信息和类的一些信息,也包括的参数的类型。
3. 调用MethodHandler方法的代码如下:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);//初始化initBinder注解的方法然后缓存
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);//处理@ModelAttribute的所有方法,过程和上面类似
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);//有调用ModelAttrbute的过程会取出方法的值和注解中的value作为name存储到model中
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();
}
}
4.视图渲染的意思:
把ModelAttribute的一些属性copy到Request中的attribute中的过程,然后调用底层的request进行视图跳转