11.1、Spring源码学习 ——SpringMVC 之 web.xml 和 DispatcherServet

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/bestcxx/article/details/98936049

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好。

SpringMVC 是针对 servlet 请求的封装

SpringMVC 为 我们提供了 完备、灵活、便捷的 servlet 请求解决方案。
其按照控制器、模型对象、分派器、处理程序解耦了整个 servlet 交互过程。
支持国际化配置、web请求、RESTful 风格请求、文件上传下载,并且和Spring 全家桶无缝隙搭配使用——尽管其更关注页面到服务器这部分。
SpringMVC 通过请求拦截、地址映射的方式组合请求和对应的处理器,然后将处理结果封装到模型对象,再由分派器

Maven依赖:本文版本 4.3.17.RELEASE

SpringMVC 基于 Spring ,其需要 Spring 基本的jar 包依赖,此外,作为 SpringMVC 的核心jar 的Maven 依赖如下

<!--https://mvnrepository.com/artifact/org.springframework/spring-webmvc/4.3.17.RELEASE-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.17.RELEASE</version>
</dependency>
<!--或许你也需要下面这个测试的类-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test-mvc</artifactId>
    <version>1.0.0.M1</version>
    <scope>test</scope>
</dependency>

SpringMVC 的入口配置:web.xml

SpringMVC 一般就是一个 web 项目,需要 web.xml 作为整个项目的入口。
在该文件中必须的配置有两个:第一个是配置servlet 的拦截路径和处理器 org.springframework.web.servlet.DispatcherServlet的映射关系,第二个是配置加载文件

配置处理器 DispatcherServlet

我们可以直接使用 DispatcherServlet 加载所有的配置文件,但是不建议这么做,而是仅在这里加载 Controller 相关的Bean和页面跳转配置
而与Spring 基础功能相关的给到 ContextLoaderListener 来加载

DispatcherServlet 默认加载文件 WEB-INF/servlet名称-servlet.xml

DispatcherServlet 默认记载 servlet 配置文件名和你的应用配置名有关,比如
< servlet-name>springmvc</ servlet-name>,它就会查找 WEB-INF/springmvc-servlet.xml
这个文件

自定义servlet 文件路径和名称

我们可以通过 < init-param> 为DispatcherServlet 自定义加载文件的位置和名称,并且,我们可以指定多个,如下

<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 默认 *-servlet.xml 文件路径为 /WEB-INF/springmvc-servlet.xml
			 通过 init-param 可以自定义配置文件路径,这里可以重复加载配置文件,后面加载的配置文件会覆盖前面的文件,但是建议只负责加载testservlet-servlet.xml
		 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-servlet.xml</param-value>
		</init-param>
		<!-- 该值大于等于0 ,在servlet 初始化时运行 HttpServlet init()方法,
        否则在第一次请求时运行且仅运行一次  HttpServlet init() 方法-->
		<load-on-startup>1</load-on-startup>
		<!-- 需Servlet 3.0 才支持,允许异步执行 servlet -->
  		<async-supported>true</async-supported>
	</servlet>
 
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

< listener>和< servlet>的关系 及最佳实践

从职能上看,< listener> 和 < servlet> 都可以加载配置文件,且二者可以加载重复的文件,后者会覆盖前者
从可取代性看,< servlet> 可以取代 < listener>,但是< servlet>不可被取代
< listener>默认加载文件为 WEB-INF/applicationContext.xml, applicationContext.xml 用于配置Spring 容器相关的基础功能Bean
< servlet>默认加载文件为 WEB-INF/servlet名称-servlet.xml,servlet名称-servlet.xml用于配置Controller、视图解析器、拦截器等前端交互相关配置
二者都可以通过再定义的方式自定义配置文件的位置
总之,< servlet> 的配置是必不可少的
从执行顺序看,< listener>会先运行,< servlet>会后运行,但是启动阶段都会运行
从数量看,二者都可以配置多个,< servlet>还能指定执行顺序

最佳实践

可以参考 SpringMVC 项目 (MAVEN) Spring MVC 入门之页面跳转

<!-- 自定义 applicationContext.xml 位置 -->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext.xml</param-value>
</context-param>
  	<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
	<servlet-name>springmvc</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!-- 默认 *-servlet.xml 文件路径为 /WEB-INF/springmvc-servlet.xml
		 通过 init-param 可以自定义配置文件路径,这里可以重复加载配置文件,但是建议只负责加载springmvc-servlet.xml
	 -->
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc-servlet.xml</param-value>
	</init-param>
	<!-- 设定值越小的servlet越先被在启动阶段运行其init()方法,一般我们只会设置一个servlet  -->
	<load-on-startup>1</load-on-startup>
	<!-- 需Servlet 3.0 才支持,允许异步执行 servlet -->
 	<async-supported>true</async-supported>
</servlet>

<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

org.springframework.web.servlet.PageNotFound noHandlerFound

如果你到项目只使用 DispatcherServlet 加载所有到配置文件,你应该不会遇到这个问题,但是当你搭配使用 ContextLoaderListener 和 DispatcherServlet 时,一定要注意,DispatcherServlet 用于加载当 servlet.xml 配置一定要连带配置 Controller 当bean,否则你的系统在访问时会报404,当然建议直接把 Controller 的bean 声明直接放入到 servlet.xml 文件中.可以参考 DispatcherServlet 必须一起加载SpringMVC 相关配置文件和Controller的bean,可以放到两个文件中

进入 DispatcherServlet

org.springframework.web.servlet.DispatcherServlet

先看下 DispatcherServlet 的类继承关系

可以看到,DispatcherServlet 间接实现了 Servlet ,此外就是SpringMVC 自己的特性类或接口了

在这里插入图片描述

SpringMVC 的默认配置文件加载:DispatcherServlet.properties

DispatcherServet 中的 static 代码块
 static {
        try {
            ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", DispatcherServlet.class);
            defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        } catch (IOException var1) {
            throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + var1.getMessage());
        }
    }
DispatcherServlet.properties 文件

DispatcherServet 中提供了一个 static 代码块,在类初始化阶段会加载默认配置文件,该文件在 spring-webmvc 包中
>该文件内容包含SpringMVC 默认的一些配置
在这里插入图片描述

参考资料

[1]、《Spring 源码深度解析》

猜你喜欢

转载自blog.csdn.net/bestcxx/article/details/98936049