一、SpringMVC简介

是一种基于JAVA实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。

解析:

1、MVC架构模式的思想:将Web层进行指责解耦

2、基于请求驱动:请求-相应模型

3、框架的目的:简化开发

二、web.xml配置说明

1、ContextLoaderListener 初始化

Spring MVC 核心处理流程

Spring MVC 核心处理流程

从图中我们可以看出ContextLoaderListener 实现了 ServletContextListener 所以在web容器启动时它就进行了配置信息的初始化

在我们的spring xml配置文件文件中 除了用于springmvc那部分,其他的配置都在ContextLoaderListener 中进行初始化

Spring MVC 核心处理流程

像这些配置文件中我们所配置的相关bean,都会在这一步被初始化到spring的bean工厂

Spring MVC 核心处理流程

2、DispatcherServlet(分发器) 初始化

Spring MVC 核心处理流程

从配置中我们可以看出,它就是一个servlert 而且 load-on-startup 为1 所以在web容器启动的时候,它就被进行了初始化,

它初始化的东西就是我们在 springMvc-servlet.xml 中配置的信息。

继承关系:

Spring MVC 核心处理流程

在web容器启动时将调用HttpServletBean中的init方法,该方法的主要作用是将servlet初始化参数(init-param)设置到该组件上,

而且HttpServletBean还提供给子类一个初始化扩展店,initServletBean(),该方法由FramewordServlet覆盖。

FrameworkServlet继承HttpServletBean 通过initServletBean()进行web上下文初始化,该方法主要覆盖以下两件事情:初始化web     上下文、提供子类初始化扩展点。

Spring MVC 核心处理流程


[java] view plain copy
  1. protected WebApplicationContext initWebApplicationContext() {  
  2.     //ROOT上下文(ContextLoaderListener加载的)  
  3.     WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());  
  4.     WebApplicationContext wac = null;  
  5.     if (this.webApplicationContext != null) {  
  6.         //1、在创建该Servlet注入的上下文  
  7.         wac = this.webApplicationContext;  
  8.         if (wac instanceof ConfigurableWebApplicationContext) {  
  9.             ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;  
  10.             if (!cwac.isActive()) {  
  11.                 if (cwac.getParent() == null) {  
  12.                     cwac.setParent(rootContext);  
  13.                 }  
  14.                 configureAndRefreshWebApplicationContext(cwac);  
  15.             }  
  16.         }  
  17.     }  
  18.     if (wac == null) {  
  19.         //2、查找已经绑定的上下文  
  20.         wac = findWebApplicationContext();  
  21.     }  
  22.     if (wac == null) {  
  23.         //3、如果没有找到相应的上下文,并指定父亲为ContextLoaderListener  
  24.         wac = createWebApplicationContext(rootContext);  
  25.     }  
  26.     if (!this.refreshEventReceived) {  
  27.         onRefresh(wac);//4、刷新上下文(执行一些初始化)  
  28.     }  
  29.     if (this.publishContext) {  
  30.         String attrName = getServletContextAttributeName();  
  31.         getServletContext().setAttribute(attrName, wac);  
  32.         if (this.logger.isDebugEnabled()) {  
  33.             this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +"' as ServletContext attribute with name [" + attrName + "]");  
  34.         }  
  35.     }  
  36.     return wac;  
  37. }  

DispatcherServlet继承FrameworkServlet,并实现了onRefresh()方法提供一些前端控制器相关的配置

Spring MVC 核心处理流程


从如上代码可以看出,DispatcherServlet启动时会进行我们需要的Web层Bean的配置,如HandlerMapping、HandlerAdapter等,而且如果我们没有     配置,还会给我们提供默认的配置。

默认配置:

Spring MVC 核心处理流程


3、ContextLoaderListener初始化上下文 和 DispatcherServlet初始化上下文的关系

Spring MVC 核心处理流程

从图中我们可以看出,ContextLoaderListener 初始化的上下文bean是对整个应用程序共享的,而DispatcherServlet 初始化的

上下文只对Spring Web Mvc有效。

三、SpringMVC处理请求流程

SpringMVC框架是一个基于请求驱动的Web框架,并且使用了‘前端控制器’模型来进行设计,再根据‘请求映射规则’分发给相应的页面控制器进行处理。

具体流程:

Spring MVC 核心处理流程

1、  首先用户 发送请求—— >DispatcherServlet , 分发器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

2、  DispatcherServlet —— >HandlerMapping , HandlerMapping 将会把请求映射为 HandlerExecutionChain 对象(包含一个 Handler 处理器(Controller)对象、多个 HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;

3、  DispatcherServlet —— >HandlerAdapter , HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

4、  HandlerAdapter —— > 处理器功能处理方法的调用, HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理(在调用处理器前会先执行spring的前置拦截器preHandle);并返回一个 ModelAndView 对象(包含模型数据、逻辑视图名),返回视图后会执行spring的后置拦截器postHandle;

5、  ModelAndView 的逻辑视图名—— > ViewResolver , ViewResolver 将把逻辑视图名解析为具体的 View,通过这种策略模式,很容易更换其他视图技术;

6、  View —— > 渲染 ,View 会根据传进来的 Model 模型数据进行渲染,此处的 Model 实际是一个 Map 数据结构,因此很容易支持其他视图技术(这步处理完后执行spring的完成后拦截器)

7、  返回控制权给 DispatcherServlet , 由 DispatcherServlet 返回响应给用户,到此一个流程结束。

DispatcherServlet 的分发控制主要是在doDispatch 中完成,接下来我来看下源码

[java] view plain copy
  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  2.         HttpServletRequest processedRequest = request;  
  3.         HandlerExecutionChain mappedHandler = null;  
  4.         boolean multipartRequestParsed = false;  
  5.   
  6.         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
  7.   
  8.         try {  
  9.             ModelAndView mv = null;  
  10.             Exception dispatchException = null;  
  11.   
  12.             try {  
  13.                 //步骤1、检查请求是否是multipart(如文件上传),如果是将通过MultipartResolver解析    
  14.                 processedRequest = checkMultipart(request);  
  15.                 multipartRequestParsed = (processedRequest != request);  
  16.   
  17.                  //步骤2、请求到处理器(页面控制器Controller)的映射,通过HandlerMapping进行映射   
  18.                 mappedHandler = getHandler(processedRequest, false);  
  19.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  20.                     noHandlerFound(processedRequest, response);  
  21.                     return;  
  22.                 }  
  23.   
  24.                 //步骤3、处理器适配,将我们的处理器包装成相应的适配器(从而支持多种类型的处理器)  
  25.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  26.   
  27.                 // Process last-modified header, if supported by the handler.  
  28.                 //304 Not Modified缓存支持    
  29.                 String method = request.getMethod();  
  30.                 boolean isGet = "GET".equals(method);  
  31.                 if (isGet || "HEAD".equals(method)) {  
  32.                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
  33.                     if (logger.isDebugEnabled()) {  
  34.                         logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);  
  35.                     }  
  36.                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
  37.                         return;  
  38.                     }  
  39.                 }  
  40.                 //执行处理器相关的拦截器的前置理(HandlerInterceptor.preHandle)   
  41.                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {  
  42.                     return;  
  43.                 }  
  44.                 //步骤4、由适配器执行处理器(调用处理器相应功能处理方法)    
  45.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  46.   
  47.                 if (asyncManager.isConcurrentHandlingStarted()) {  
  48.                     return;  
  49.                 }  
  50.                 applyDefaultViewName(request, mv);  
  51.                 //执行处理器相关的拦截器的后处理(HandlerInterceptor.postHandle)    
  52.                 mappedHandler.applyPostHandle(processedRequest, response, mv);  
  53.             }  
  54.             catch (Exception ex) {  
  55.                 dispatchException = ex;  
  56.             }  
  57.             //这里面执行了处理器相关拦截器的完成后处理(HandlerInterceptor.afterCompletion)  
  58.             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);  
  59.         }  
  60.         catch (Exception ex) {  
  61.             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);  
  62.         }  
  63.         catch (Error err) {  
  64.             triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);  
  65.         }  
  66.         finally {  
  67.             if (asyncManager.isConcurrentHandlingStarted()) {  
  68.                 // Instead of postHandle and afterCompletion  
  69.                 if (mappedHandler != null) {  
  70.                     mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);  
  71.                 }  
  72.             }  
  73.             else {  
  74.                 // Clean up any resources used by a multipart request.  
  75.                 if (multipartRequestParsed) {  
  76.                     cleanupMultipart(processedRequest);  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
到此我们已经简单的了解了 Spring  MVC 核心的处理流程

一、SpringMVC简介

是一种基于JAVA实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。

解析:

1、MVC架构模式的思想:将Web层进行指责解耦

2、基于请求驱动:请求-相应模型

3、框架的目的:简化开发

二、web.xml配置说明

1、ContextLoaderListener 初始化

Spring MVC 核心处理流程

Spring MVC 核心处理流程

从图中我们可以看出ContextLoaderListener 实现了 ServletContextListener 所以在web容器启动时它就进行了配置信息的初始化

在我们的spring xml配置文件文件中 除了用于springmvc那部分,其他的配置都在ContextLoaderListener 中进行初始化

Spring MVC 核心处理流程

像这些配置文件中我们所配置的相关bean,都会在这一步被初始化到spring的bean工厂

Spring MVC 核心处理流程

2、DispatcherServlet(分发器) 初始化

Spring MVC 核心处理流程

从配置中我们可以看出,它就是一个servlert 而且 load-on-startup 为1 所以在web容器启动的时候,它就被进行了初始化,

它初始化的东西就是我们在 springMvc-servlet.xml 中配置的信息。

继承关系:

Spring MVC 核心处理流程

在web容器启动时将调用HttpServletBean中的init方法,该方法的主要作用是将servlet初始化参数(init-param)设置到该组件上,

而且HttpServletBean还提供给子类一个初始化扩展店,initServletBean(),该方法由FramewordServlet覆盖。

FrameworkServlet继承HttpServletBean 通过initServletBean()进行web上下文初始化,该方法主要覆盖以下两件事情:初始化web     上下文、提供子类初始化扩展点。

Spring MVC 核心处理流程


[java] view plain copy
  1. protected WebApplicationContext initWebApplicationContext() {  
  2.     //ROOT上下文(ContextLoaderListener加载的)  
  3.     WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());  
  4.     WebApplicationContext wac = null;  
  5.     if (this.webApplicationContext != null) {  
  6.         //1、在创建该Servlet注入的上下文  
  7.         wac = this.webApplicationContext;  
  8.         if (wac instanceof ConfigurableWebApplicationContext) {  
  9.             ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;  
  10.             if (!cwac.isActive()) {  
  11.                 if (cwac.getParent() == null) {  
  12.                     cwac.setParent(rootContext);  
  13.                 }  
  14.                 configureAndRefreshWebApplicationContext(cwac);  
  15.             }  
  16.         }  
  17.     }  
  18.     if (wac == null) {  
  19.         //2、查找已经绑定的上下文  
  20.         wac = findWebApplicationContext();  
  21.     }  
  22.     if (wac == null) {  
  23.         //3、如果没有找到相应的上下文,并指定父亲为ContextLoaderListener  
  24.         wac = createWebApplicationContext(rootContext);  
  25.     }  
  26.     if (!this.refreshEventReceived) {  
  27.         onRefresh(wac);//4、刷新上下文(执行一些初始化)  
  28.     }  
  29.     if (this.publishContext) {  
  30.         String attrName = getServletContextAttributeName();  
  31.         getServletContext().setAttribute(attrName, wac);  
  32.         if (this.logger.isDebugEnabled()) {  
  33.             this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +"' as ServletContext attribute with name [" + attrName + "]");  
  34.         }  
  35.     }  
  36.     return wac;  
  37. }  

DispatcherServlet继承FrameworkServlet,并实现了onRefresh()方法提供一些前端控制器相关的配置

Spring MVC 核心处理流程


从如上代码可以看出,DispatcherServlet启动时会进行我们需要的Web层Bean的配置,如HandlerMapping、HandlerAdapter等,而且如果我们没有     配置,还会给我们提供默认的配置。

默认配置:

Spring MVC 核心处理流程


3、ContextLoaderListener初始化上下文 和 DispatcherServlet初始化上下文的关系

Spring MVC 核心处理流程

从图中我们可以看出,ContextLoaderListener 初始化的上下文bean是对整个应用程序共享的,而DispatcherServlet 初始化的

上下文只对Spring Web Mvc有效。

三、SpringMVC处理请求流程

SpringMVC框架是一个基于请求驱动的Web框架,并且使用了‘前端控制器’模型来进行设计,再根据‘请求映射规则’分发给相应的页面控制器进行处理。

具体流程:

Spring MVC 核心处理流程

1、  首先用户 发送请求—— >DispatcherServlet , 分发器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

2、  DispatcherServlet —— >HandlerMapping , HandlerMapping 将会把请求映射为 HandlerExecutionChain 对象(包含一个 Handler 处理器(Controller)对象、多个 HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;

3、  DispatcherServlet —— >HandlerAdapter , HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

4、  HandlerAdapter —— > 处理器功能处理方法的调用, HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理(在调用处理器前会先执行spring的前置拦截器preHandle);并返回一个 ModelAndView 对象(包含模型数据、逻辑视图名),返回视图后会执行spring的后置拦截器postHandle;

5、  ModelAndView 的逻辑视图名—— > ViewResolver , ViewResolver 将把逻辑视图名解析为具体的 View,通过这种策略模式,很容易更换其他视图技术;

6、  View —— > 渲染 ,View 会根据传进来的 Model 模型数据进行渲染,此处的 Model 实际是一个 Map 数据结构,因此很容易支持其他视图技术(这步处理完后执行spring的完成后拦截器)

7、  返回控制权给 DispatcherServlet , 由 DispatcherServlet 返回响应给用户,到此一个流程结束。

DispatcherServlet 的分发控制主要是在doDispatch 中完成,接下来我来看下源码

[java] view plain copy
  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  2.         HttpServletRequest processedRequest = request;  
  3.         HandlerExecutionChain mappedHandler = null;  
  4.         boolean multipartRequestParsed = false;  
  5.   
  6.         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
  7.   
  8.         try {  
  9.             ModelAndView mv = null;  
  10.             Exception dispatchException = null;  
  11.   
  12.             try {  
  13.                 //步骤1、检查请求是否是multipart(如文件上传),如果是将通过MultipartResolver解析    
  14.                 processedRequest = checkMultipart(request);  
  15.                 multipartRequestParsed = (processedRequest != request);  
  16.   
  17.                  //步骤2、请求到处理器(页面控制器Controller)的映射,通过HandlerMapping进行映射   
  18.                 mappedHandler = getHandler(processedRequest, false);  
  19.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  20.                     noHandlerFound(processedRequest, response);  
  21.                     return;  
  22.                 }  
  23.   
  24.                 //步骤3、处理器适配,将我们的处理器包装成相应的适配器(从而支持多种类型的处理器)  
  25.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  26.   
  27.                 // Process last-modified header, if supported by the handler.  
  28.                 //304 Not Modified缓存支持    
  29.                 String method = request.getMethod();  
  30.                 boolean isGet = "GET".equals(method);  
  31.                 if (isGet || "HEAD".equals(method)) {  
  32.                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
  33.                     if (logger.isDebugEnabled()) {  
  34.                         logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);  
  35.                     }  
  36.                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
  37.                         return;  
  38.                     }  
  39.                 }  
  40.                 //执行处理器相关的拦截器的前置理(HandlerInterceptor.preHandle)   
  41.                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {  
  42.                     return;  
  43.                 }  
  44.                 //步骤4、由适配器执行处理器(调用处理器相应功能处理方法)    
  45.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  46.   
  47.                 if (asyncManager.isConcurrentHandlingStarted()) {  
  48.                     return;  
  49.                 }  
  50.                 applyDefaultViewName(request, mv);  
  51.                 //执行处理器相关的拦截器的后处理(HandlerInterceptor.postHandle)    
  52.                 mappedHandler.applyPostHandle(processedRequest, response, mv);  
  53.             }  
  54.             catch (Exception ex) {  
  55.                 dispatchException = ex;  
  56.             }  
  57.             //这里面执行了处理器相关拦截器的完成后处理(HandlerInterceptor.afterCompletion)  
  58.             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);  
  59.         }  
  60.         catch (Exception ex) {  
  61.             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);  
  62.         }  
  63.         catch (Error err) {  
  64.             triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);  
  65.         }  
  66.         finally {  
  67.             if (asyncManager.isConcurrentHandlingStarted()) {  
  68.                 // Instead of postHandle and afterCompletion  
  69.                 if (mappedHandler != null) {  
  70.                     mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);  
  71.                 }  
  72.             }  
  73.             else {  
  74.                 // Clean up any resources used by a multipart request.  
  75.                 if (multipartRequestParsed) {  
  76.                     cleanupMultipart(processedRequest);  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
到此我们已经简单的了解了 Spring  MVC 核心的处理流程

相关文章: