spring Mvc 执行原理 及 xml注解配置说明 (六)
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; @Override
public 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;
} @Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
System.out.println("after posthandler");
} @Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
System.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>
spring Mvc 执行原理 及 xml注解配置说明 (六)的更多相关文章
- (4.1)Spring MVC执行原理和基于Java的配置过程
一.Spring MVC执行原理和基于Java配置的配置过程 (一)Spring MVC执行过程,大致为7步. 所有的请求都会经过Spring的一个单例的DispacherServlet. Dispa ...
- Spring MVC执行原理和基于Java的配置过程
一.Spring MVC执行原理和基于Java配置的配置过程 (一)Spring MVC执行过程,大致为7步. 所有的请求都会经过Spring的一个单例的DispacherServlet. Dispa ...
- Spring MVC执行原理
spring的MVC执行原理 1.spring mvc将所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求 进行真正的处理工作. 2.DispatcherSer ...
- Spring MVC 工作原理和流程、注解
Spring MVC 是实现MVC设计模式的企业级开发框架,是Spring框架的一个子模块,无需整合,开发起来更加便捷. MVC设计模式 MVC是一种设计模式,它将应用程序分为 Controller. ...
- spring的MVC执行原理
spring的MVC执行原理 1.spring mvc将所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求 进行真正的处理工作. 2.DispatcherSer ...
- Spring MVC工作原理(好用版)
Spring MVC工作原理 参考: SpringMVC工作原理 - 平凡希 - 博客园https://www.cnblogs.com/xiaoxi/p/6164383.html SpringMVC的 ...
- Spring MVC执行的流程
1.Spring MVC应用的开发步骤 a.在web.xml文件中定义前端控制器DispatcherServlet来拦截用户请求.由于Web应用是基于请求/响应架构的应用,所以 不管哪个MVC Web ...
- Spring MVC简单原理
Spring MVC原理 针对有Java Web基础.Spring基础和Spring MVC使用经验者. 前言 目前基于Java的web后端,Spring生态应该是比较常见了.虽然现在流行前后端分离, ...
- 一文读懂Spring MVC执行流程
说到Spring MVC执行流程,网上有很多这方面的文章介绍,但是都不太详细,作为一个初学者去读会有许多不理解的地方,今天这篇文章记录一下我学习Spring MVC的心得体会 话不多说,先上图: ...
随机推荐
- opencv core组件进阶
1.图像在内存中存储方式,图像矩阵的大小取决于颜色模型,取决于所有的通道数:还有重要的颜色空间缩减的概念:因为如果是RGB的话,使用uchar的话,就有256^3的结合方法.所以要用到颜色缩减的方法, ...
- Unity之日志管理
1. 目录结构 1. Plugins --> 存放Log4Net动态库文件 2. Scripts --> 存放写日志的脚本 3. StreamingAssets -->存放Log4N ...
- LintCode——旋转字符串
描述:给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例:对于字符串 "abcdefg" offset=0 => "abcdefg&qu ...
- 当activity改变时,我们如何处理它
用户和系统触发的事件,可能造成一个activity状体的改变.这个文档描述了一些常见的情况,和如何去处理这些改变. 原网站:https://developer.android.google.cn/g ...
- 在Ubuntu虚拟机上安装DVWA
学习资料来源:https://www.neddos.tech/?p=107 最后更新时间: 190122·17:41 1> 什么是DVWA(Damn Vulnerable Web Applica ...
- C语言函数参数传递
1.值传递 void swap(int x,int y) { int temp = x; x = y; y = temp; } void main() { , b = ; swap(a, b); } ...
- CentOS下 NFS的简单使用以及windows 关在linux的NFS存储方法
1. 全部安装的情况下NFS已经安装到服务器上面了,如果没有安装的话 需要使用如下命令进行安装 yum -y install nfs-utils rpcbind 2. 创建需要使用的NFS目录 mkd ...
- C语言变长数组data[0]
1.前言 在刷题时遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data[0] ...
- Spring之c3p0连接池xml配置和使用举例
1.导入jar包 c3p0-0.9.5.2.jar mchange-commons-java-0.2.11.jar 2.源码: beans.xml <beans xmlns="http ...
- ES6学习笔记(三):与迭代相关的新东东
Symbol 概念 Symbol:一种新的原始数据类型,表示独一无二的值. 注意:Symbol函数的参数只是表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的. // 没 ...