Spring MVC 执行原理

在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet 处理;

一个Spring MVC工程里,可以配置多个的 dispatcherServlet ,每个 DispatcherServlet 可以对应多个的 HandlerMapping ,每个 HandlerMapping 可以有自己的 Interceptor (拦截器)。

1. 请求首先 由 前端 DispatcherServlet 捕获;

2. DispatcherServlet 经过 HandlerMapping 获取适当的 Hanlder ,也即 Controller ,并返回给 DispatcherServlet;

3. 如果有设置 拦截器,首选执行拦截器的 preHandler 方法,并把执行结果返回 DispatcherServlet;

4. DispatcherServlet 根据捕获的请求,以及 Handler (Controller) ,获取到适当的 HandlerAdapter 处理,并把结果返回给 DispatcherServlet,结果为 (View 和 Model);

5. 如果有设置拦截器,就是执行 拦截器的 postHandler 方法,并返回 DispatcherServlet;

6. DispatcherServlet 根据获取的 view 跟 model 结合 ViewResolver,返回所指的 视图模板,并返回给 DispatcherServlet;

7. DispatcherServlet 结合 视图模型跟model ,执行 render() 渲染界面,并返回给客户端;

一个DispatcherServlet 都有自己 上下文配置文件, 这个配置继承自根的上下文配置文件;

每个 DispatcherServlet 都可配置多个不同的 HandlerMapping 映射方式;每个 HandlerMapping 都实现了 Ordered 接口,可以上下文文件配置中设置优先使用的 HandlerMapping;

用户的请求被 DispatcherServlet 捕获后,DispatcherServlet 使用优先级高的 HandlerMapping 查找可用的 Handler,如果没有找到合适的 Handler,就使优先级次之的 HandlerMapping 继续查找,直到找到为止;

比如:Spring MVC 提供主要的 HanderMapping 有 DefaultAnnotationHandlerMapping, SimpleUrlHandlerMapping, BeanNameUrlHandlerMapping

<bean id="defaultAnnoHandlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"><property name="order" value="1"/>
</bean><bean id="simpleUrlMapping" class="org.
springframework.Web.servlet.handler.SimpleUrlHandlerMapping"><property name="order" value="2"/><!--  ... -->
</bean><bean id="beanNameUrlMapping" class="org.springframework.Web.servlet.
handler.BeanNameUrlHandlerMapping"><!-- ... -->
</bean>

如果不为HandlerMapping明确指定order,那么默认值为Integer.MAX_VALUE,对应最低优先级。

如果 DefaultAnnotationHandlerMapping 找到相应的 Handler ,就把数据传给相应的 Controller 类下的相应的 HandlerAdapter (方法处)处理;如果没有找到,就到 SimpleUrlHandlerMapping 处理;

Spring MVC xml配置说明

1. Web.xml 配置

1>. 首先 Spring 监听器:

<!-- Creates the Spring Container shared by all Servlets and Filters --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

它是整个 spring 框架的入口,会自动装载 应用程序根上下文的 配置文件;因为他实现了 ServletContextListener 这个接口,项目启动时,就会执行它实现的方法。

2>. 根应用程序上下文配置:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/root-context.xml</param-value></context-param>

也可叫 spring 全局配置,在这里可以配置 数据源 等一些 全局的spring 基本的配置;dispatcherServlet 可以继承自这里的配置;

3>. diapatcherServlet 配置:

<!-- Processes application requests --><servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>appServlet</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>

load-on-startup 值为 "1" 表示该 servlet (dispatcherServlet 也是一个 servlet) 随 servlet 容器同时启动。

dispatcherservlet 的 init-param 节点不是必须的,如果没有配置,该 dispatcherServlet 对应的 上下文配置文件 就会到 /WEB-INF/[servlet-name]-servlet.xml 加载;

servlet-mapping 的 url-pattern 的值 "*.do" 表示,servlet 只会拦截 .do 后缀的请求,这种配置不会影响静态资源的访问。

4>. 配置工程项目编码:

<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

该过滤器如果没有配置,请求访问可能会遇乱码;

-------------------------------------------------------------

现在配置 diapatcherServlet 对应的 上下文配置文件: /WEB-INF/spring/appServlet/servlet-context.xml (上面配置的)

1>.  启动扫描所有的 Controller

<context:component-scan base-package="com.study.web"/>

主要作用于 @Controller,假如他的包结构是这样的:

com.study.web

|---controller

|-----|-----abcController.java

   |-----cdeController.java

那么上面的 base-package 写为 com.study.web.controller 也是正确的;

2>. <mvc:annotation-driven /> 说明:

是一种简写形式,可以让初学者快速成应用默认的配置方案,会默认注册 DefaultAnnotationHandleMapping以及AnnotionMethodHandleAdapter 这两个 Bean, 这两个 Bean ,前者对应类级别, 后者对应到方法级别;

上在面的 DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter 是 Spring 为 @Controller 分发请求所必需的。

annotation-driven 扫描指定包中类上的注解,常用的注解有:

@Controller 声明Action组件
@Service 声明Service组件 @Service("myMovieLister")
@Repository 声明Dao组件
@Component 泛指组件, 当不好归类时.
@RequestMapping("/menu") 请求映射
@Resource 用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")
@Autowired 用于注入,(srping提供的) 默认按类型装配
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype") 设定bean的作用域

3>. 视图解析类,对模型视图名称的解析,在请求时模型视图名称添加前后缀

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean>

InternalResourceViewResolver 提供了对 JstlView 的支持: <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />

Spring Mvc 2.5 版本以前,提供了 注解 功能,实现了对 REST 的全面支持; REST 通过不带扩展名的 URL 来访问系统资源;REST 会把每个请求资源当成是静态,每个 URL 资源都是一个静态资源;

它通 @RequestMapping主@PathVariable 注释提供访问映射,由@RequestMapping 中的 value 及 method 就可以支持Rest式的访问。

通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

比如 使用的是 Velocity 技术,那么只要把 suffix 的 value 值改为 ".vm" 即可;

4>.  Spring 拦截器:

全局配置:

<mvc:interceptors><bean class="com.study.web.interceptor.MyInterceptor"></bean></mvc:interceptors>

基于路径的拦截器:

<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**/*.do"/><beans:bean class="com.study.interceptor.utils.StuInterceptor"><beans:property name="startWrk"><beans:value>1</beans:value></beans:property><beans:property name="endWrk"><beans:value>24</beans:value></beans:property><beans:property name="redirectUrl"><beans:value>http://127.0.0.1:8080/interceptor/static/timeout.htm</beans:value></beans:property></beans:bean></mvc:interceptor></mvc:interceptors>

相关的 Java 类 : StuInterceptor ( 该类的作用是拦截在指定的时间范围外,则页面请求转到/interceptor/static/timeout.htm )

package com.study.interceptor.utils;import java.util.Calendar;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.study.interceptor.controller.HomeController;public class StuInterceptor  implements HandlerInterceptor /*extends HandlerInterceptorAdapter*/ {private static final Logger logger = LoggerFactory.getLogger(HomeController.class);private int startWrk;private int endWrk;private String redirectUrl;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {logger.info("Interceptor", "I am in Custom Interceptor!");Calendar cal = Calendar.getInstance();int hour = cal.get(Calendar.HOUR_OF_DAY);if (hour > startWrk && hour < endWrk) {return true;} else {response.sendRedirect(redirectUrl);return false;}}public int getStartWrk() {return this.startWrk;}public void setStartWrk(int startWrk) {this.startWrk = startWrk;}public int getEndWrk() {return this.endWrk;}public void setEndWrk(int endWrk) {this.endWrk = endWrk;}public String getRedirectUrl() {return this.redirectUrl;}public void setRedirectUrl(String redirectUrl) {this.redirectUrl = redirectUrl;}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// TODO Auto-generated method stubSystem.out.println("after posthandler");  }@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stubSystem.out.println("after completion");  }
}

5>. 在 HandlerMapping 内配置拦截器:

<!-- Mapping -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  <property name="mappings">  <props>  <prop key="/abc.do">abcController</prop>  <prop key="def.kara">defController</prop>   </props>  </property>  <!-- 注册拦截器 -->  <property name="interceptors">  <list>  <ref bean="myInterceptor"></ref>  </list>  </property>
</bean>  

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean class="com.study.web.MyInteceptor"></bean>
</list>
</property>
</bean>

6>. 使用 placeHolder 加载应用程序属性配置文件

<context:property-placeholder location="/WEB-INF/config.properties"/>

比如 加载 mysql jdbc 配置信息:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springdb
username=root
password=123

那么 mysql 的数据源配置的 驱动信息,用户信息,就可以配置成这样:

<context:property-placeholder location="classpath:META-INF/mybatis/mysql.properties" /><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${driver}"></property><property name="url" value="${url}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property></bean>

转载于:https://www.cnblogs.com/editor/p/3895439.html

spring Mvc 执行原理 及 xml注解配置说明 (六)相关推荐

  1. Spring MVC 执行过程原理(请求映射原理、参数处理原理、返回值处理器)

    Spring MVC 执行过程分析 文章目录 Spring MVC 执行过程分析 请求映射原理 适配器Adapter 执行目标方法 参数处理器解析器HandlerMethodArgumentResol ...

  2. Spring Mvc工作原理图解

    Spring Mvc工作原理图解 先来一张图: 目前还是有些疑惑,因为是初学 思考了大半天,整理了初步的一些工作原理: 如图上所述: 1.用户(打开网站,输入网址url)发送请求. 2.用户的请求会通 ...

  3. Spring MVC工作原理

    转载自  Spring MVC工作原理 Spring MVC框架介绍 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring M ...

  4. Spring MVC工作原理 及注解说明

    转载自  http://blog.csdn.net/shuyeshangdemayi/article/details/50259493 SpringMVC框架介绍 1) Spring MVC属于Spr ...

  5. Spring MVC执行流程及原理

    面试找虐 博主之前每次去面试必问的问题:"讲一下spring mvc的执行流程以及常用组件的作用": 记得第一次和面试官说了大概的流程是这样的:"服务器收到一个请求后会先 ...

  6. 详细述说spring mvc工作原理

    spring mvc是什么? springMVC是一个MVC的开源框架,springMVC=struts2+spring,springMVC就相当于是Struts2加上sring的整合,但是这里有一个 ...

  7. Spring Boot Spring MVC异常处理原理分析

    一.Spring MVC为处理异常的前期准备 DispatcherServlet 入口类,是一个Servlet,是所有请求的分发点 初始化 DispatcherServlet在初始化时会触发onRef ...

  8. 如何用Java类配置Spring MVC(不通过web.xml和XML方式)

    DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置方式, XML看起来太累, 冗长繁琐. 还好借助于Servl ...

  9. Spring mvc ContextLoaderListener 原理解析

    对于熟悉Spring MVC功能,首先应从web.xml 开始,在web.xml 文件中我们需要配置一个监听器 ContextLoaderListener,如下. <!-- 加载spring上下 ...

最新文章

  1. 原来这部电影 18 禁?用神经网络“看”剧本,AI 秒给预测评级
  2. 得到win7 win8的桌面句柄
  3. SEO数据监控技巧都有哪些?
  4. svn trunk branches tags 的用法
  5. [ZJOI2008] 树的统计(树链剖分)
  6. 创建Maven源代码和Javadoc工件
  7. ntp时间同步服务器配置
  8. 微博预期12月8日登陆港交所 最终发售价定为272.8港元
  9. Jquery学习(三)选择
  10. 《推荐系统笔记(一)》线性回归方法的数学推导
  11. Keras版的GCN代码学习
  12. [收藏学习]Openstack中Keystone及dashboard安装参考
  13. 抓取html文件swf,如何把网页上的flash动画保存为swf格式文件(缓存提取)
  14. java随机数生成方法
  15. 百分字符知识付费教程
  16. 自动控制理论(1)——自动控制理论概述
  17. socks代理转http代理
  18. ml sparksql 数据比较_Spark 及其上层应用 SparkSQL(六)
  19. python 欠采样_欠采样(undersampling)和过采样(oversampling)会对模型带来怎样的影响?...
  20. Sublime 初始化

热门文章

  1. 机器学习核心概念、常用术语整理(建议收藏)
  2. 操作系统原理 —— 操作系统概述
  3. 计算机网络——数据帧和数据包的区别
  4. 计算机视觉:相机成像原理:世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换(转载)
  5. 运动目标检测单高斯背景建模
  6. VC2008以资源形式实现多语言版本
  7. JQuery EasyUI入门
  8. Python GUI界面编程初步 05- GUI框架PyQt的运用 - 02 PyQt的信号和槽例子
  9. [shell][001] [advanced]定制化自己的shell命令
  10. 小米8护眼模式无效_雷军没有交代的小米9的N个细节,这篇文章全告诉你了