001-springmvc之原理图
1、流程。

2、时序图。

3、方法调用。
(0)DispatcherServlet类。提供了HandlerMapping成员关联关系。
/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver; /** LocaleResolver used by this servlet */
private LocaleResolver localeResolver; /** ThemeResolver used by this servlet */
private ThemeResolver themeResolver; /** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings; /** List of HandlerAdapters used by this servlet */
private List<HandlerAdapter> handlerAdapters; /** List of HandlerExceptionResolvers used by this servlet */
private List<HandlerExceptionResolver> handlerExceptionResolvers; /** RequestToViewNameTranslator used by this servlet */
private RequestToViewNameTranslator viewNameTranslator; /** FlashMapManager used by this servlet */
private FlashMapManager flashMapManager; /** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;
(1)、DispatcherServlet类。
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (logger.isDebugEnabled()) {
String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
" processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
} // 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;
if (WebUtils.isIncludeRequest(request)) {
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()); FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager); try {
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
(2)、DispatcherServlet类。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
(3)、DispatcherServlet类。通过传入请求request参数,返回处理器执行器链。方法内部通过遍历List类型的成员变量HandlerMapping的getHandler获取处理器执行链对象。这个servlet所支持的处理器映射器的集合,这里有N个处理器映射器。hm就是指HandlerMapping ,下面的if中的代码是指记录日志,日志跟踪。HandlerMapping处理器映射器中有N个拦截器,处理客服端请求的处理器只有一个,就是handler处理器。
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
(4)、AbstractHandlerMapping类。
通过传入request参数,返回HandlerExecutionChain。内部通过获取与request对应的唯一处理器handler,然后将请求和handler封装成一个链。
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
} HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
(5)、AbstractHandlerMapping类。
将请求和handler封装成一个链。
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
(6)、处理器执行链HandlerExecutionChain类。直接返回处理器给中央调度器。
public Object getHandler() {
return this.handler;
}
(7)、HandlerAdapter类。
通过传入处理器参数,获取与处理器对应的一个处理器适配器。将获取到的处理器适配器返回给中央调度器。
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
for (HandlerAdapter ha : this.handlerAdapters) {
if (logger.isTraceEnabled()) {
logger.trace("Testing handler adapter [" + ha + "]");
}
if (ha.supports(handler)) {
return ha;
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
(8)、SimpleControllerHandlerAdapter类。
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { return ((Controller) handler).handleRequest(request, response);
}
(9)、
(10)、
(2)、
(3)、
(1)、
(2)、
(3)、
(1)、
(2)、
(3)、
(1)、
(2)、
(3)、
001-springmvc之原理图的更多相关文章
- 三层架构,Struts2,SpringMVC实现原理图
三层架构,Struts2,SpringMVC实现原理图 三层架构实现原理 Struts2实现原理 SpringMVC实现原理
- 001 SpringMVC的helloWorld程序
一:helloworld程序 1.结构目录 2.添加lib包 3.在web.xml中配置DispatchServlet 这个就是主servlet. <?xml version="1.0 ...
- springMVC工作原理图
- 转载:SpringMVC的工作原理图
SpringMVC的工作原理图: SpringMVC流程 1. 用户发送请求至前端控制器DispatcherServlet. 2. DispatcherServlet收到请求调用HandlerMa ...
- SpringMVC的工作原理图
SpringMVC的工作原理图: SpringMVC流程 1. 用户发送请求至前端控制器DispatcherServlet. 2. DispatcherServlet收到请求调用HandlerMa ...
- 框架SpringMVC笔记系列 一 基础
主题:SpringMVC 学习资料参考网址: 1.http://www.icoolxue.com 2.http://aokunsang.iteye.com/blog/1279322 1.SpringM ...
- springmvc(一) springmvc框架原理分析和简单入门程序
springmvc这个框架真的非常简单,感觉比struts2还更简单,好好沉淀下来学习~ --WH 一.什么是springmvc? 我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解 ...
- SpringMVC运行原理
一.SpringMVC运行原理图 二.相关接口解释 DispatcherServlet接口: Spring提供的前端控制器,所有的请求都有经过它来统一分发.在DispatcherServlet将请 ...
- SpringMVC学习(一)———— springmvc框架原理分析和简单入门程序
一.什么是springmvc? 我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交 ...
- springmvc框架原理分析和简单入门程序
一.什么是springmvc? 我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交 ...
随机推荐
- (使用lua++)Lua脚本和C++交互(四)
上一篇中,你已经可以在Lua里面用C++的函数了,那么咱们再增加一点难度,比如,我有一个CTest对象,要作为一个参数,传输给func_Add()执行,怎么办?很简单,如果你对上面的代码仔细阅读,你会 ...
- Swift-'!','?'用法
///'!','?','as'的用法 ///'!'与'?'用法与可选类型(Optional) ///首先要了解Optional类型包括什么, ///Optional类型的值包括: 1.nil 2.值 ...
- (转)淘淘商城系列——中文分析器IK-Analyzer的使用
在Solr中默认是没有中文分析器的,需要手工配置,配置一个FieldType,在FieldType中指定使用的中文分析器.另外,Solr中的字段(即业务域)必须先定义后使用.下面我们先把中文分析器配好 ...
- android基础---->Fragment的使用
碎片(Fragment)是一种可以嵌入在活动当中的UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛. Fragment的基础例子
- MyBatis——Mapper XML 文件
Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...
- 关于font-size对垂直居中影响的问题
背景:三个inline-block元素,其中两个内容为空,另外一个包含文字,设置文字的font-size之后,原本垂直居中的三个inline-block的元素,会变的不再垂直居中. 原因: 当设置了f ...
- 不同linux下两网卡绑定方法
记得原来在做性能测试时,为了提高网络吞吐率.必须将两个网卡绑定一起工作.绑定方法如下: 一.CentOS 配置 1.编辑虚拟网络接口配置文件,指定网卡IP: # vi /etc/sysconfig ...
- mysql如何用sql增加字段和注释?
alter table warn_user_binding add is_valid varchar(10) default 'true' COMMENT '删除标识:true 有效:false 删除 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- Floyd求字典序最小的路径
hdu1384 Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...