一、springMVC流程分析
1、一次请求的url流程
- (1)客户端发起的请求request通过核心处理器DispatcherServlet进行处理
- (2-3)核心处理器DispatcherServlet通过注册在spring中的HandlerMapping找到对应的Handler(其实是HandlerMethod,可以认为是我们编写的某个Controller对象的具体的某个方法 即通过映射器将请求映射到Controller的方法上),同时将注册在spring中的所有拦截器和Handler包装成执行链HandlerExecutionChain并返回给核心处理器DispatcherServlet
- (4)核心处理器DispatcherServlet 通过2-3部获取的Handler来查找对应的处理器适配器HandlerAdapter
- (5-7) 适配器调用实现对应接口的处理器,并将结果返回给适配器,结果中包含数据模型和视图对象,再由适配器返回给核心控制器
- (8-9)核心控制器将获取的数据和视图结合的对象传递给视图解析器,获取解析得到的结果,并由视图解析器响应给核心控制器
- (10)核心控制器将结果Response返回给客户端
二、springMVC源码解析
DisplaceServlet的初始化操纵请参考:https://blog.csdn.net/panyongcsd/article/details/52416279L
以下是针对DisplaceServlet初始化后进行的操作
1、springMVC的入口文件DispatcherServlet类 该类在web.xml中进行了配置
2、doService()方法 每一次的http请求都会进行该方法中
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//如果是debug状态 则打印调试相关日志
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
String resumed = WebAsyncUtils.getAsyncManager(request)
.hasConcurrentResult() ? " resumed" : "";
logger.debug("DispatcherServlet with name '"
+ getServletName() + "'" + resumed +
" processing " + request.getMethod() +
" request for [" + requestUri + "]");
}
// Keep a snapshot of the request attributes in case of an include,
// to be able to restore the original attributes after the include.
Map<String, Object> attributesSnapshot = null;
//获取该DispatcherServlet中是否含有包含(include)的servlet
//类似于<jsp:incluede page="xxx.jsp"/> 即在该jsp(servlet)中含有 xxx.jsp servlet
if (WebUtils.isIncludeRequest(request)) {
logger.debug("Taking snapshot of request attributes before include");
//将请求中的所有参数放置到快照属性Map
attributesSnapshot = new HashMap<String, Object>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude ||
attrName.startsWith("org.springframework.web.servlet")) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// Make framework objects available to handlers and view objects.
//设置上下文环境
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,
getWebApplicationContext());
//设置本地解析
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
//设置主题解析
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
//设置主题资源信息
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());、
//从session中获取flashmap 属性 不为null的时候 将其添加到request
//flashMap其实是为了重定向的时候隐式的出传递参数使用的
//每次处理请求时,都会先判断一下FlashMap中是否有数据
// 如果有就先设置到 inputFlashMap里面,也就是保存上次转发过来的属性 再设置到Model里面
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(
request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE,
Collections.unmodifiableMap(inputFlashMap));
}
//如果重定向没有传递过来参数,则保存相关的空的对象
request.set