这篇分享开始对SpringMVC进行学习。在讨论之前相信大部分都或多或少使用过SpringMVC,因为这个SpringMVC框架简单易用,代码结构清晰,而且其可拓展性等优势也非常明显,也因此目前来说SpringMVC依旧是许多开发者选择使用的技术框架。
既然SpringMVC这么强大,那就让我们开始了解这个强大的工具吧。
在学习之前,一如既往先提出学习目标,通过本文及关联文章的学习,我们会学习了解以下知识:
(1)SpringMVC的工作流程;
(2)SpringMVC的XML方式搭建应用,包括DispatcherServlet,ContextLoaderListener,视图解析器,消息转换器等配置,关于拦截器,过滤器等常用知识这里暂时不做演示,在源码中关于这两个知识点也会稍微提及不做主线研究;
(3)Servlet3.0的SPI规范;
(4)SpringMVC的零XML(即全Java代码)方式搭建应用,包括DispatcherServlet,ContextLoaderListener,视图解析器,消息转换器等配置;
(5)SpringMVC应用怎么配置和使用内置Tomcat发布应用;
(6)SpringMVC流程源码分析及涉及组件剖析和SpringMVC知识点(父子容器,SpringBoot对SpringMVC拓展的例子等);
(7)结合对源码流程解析和内部组件功能分析,手写一个自己的简易版SpringMVC框架并打包成可工程引用的jar提交到github;
关于SpringMVC的官方文档说明,可以查阅https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc
一.SpringMVC的工作流程,也就是SpringMVC是怎么接收处理以及响应一个请求?
上图就是SpringMVC的工作流程图:
1.首先用户发送http请求到前端控制器DispatchServlet上,
2.前端控制器调用映射处理器HandlerMappings,HandlerMapping根据配置或注解找到具体处理器handler,
3.HandlerMapping将具体handler返回给DispatchServlet,
4.前端控制器拿着handler去请求HandlerAdatpers,找到一个与handler匹配的适配器Adapter,
5.通过适配器传入请求和具体的处理器handler(Controller或Action),执行handler方法处理请求,
6.handler被执行完毕后返回ModelAndView给处理器适配器HandlerAdatper,
7.HandlerAdatper将得到的ModelAndView返回给前端控制器,
8.前端控制器将ModelAndView传给视图解析器ViewResolver,
9.视图解析器对ViewResource进行解析后返回具体的VIew给前端控制器,
10.前端控制器根据View进行渲染视图(将模型数据填充到视图中),
11.把渲染好的视图把过response响应给用户。
以上就是关于SpringMVC从接收一个请求到响应一个请求的工作过程。在这个工作过程中我们可以看到有诸多组件相互配合使用,如DispatchServlet,HandlerMappings,HandlerAdatpers,ModelAndView,ViewResolver,VIew等等。
那么,初步了解了这个工作原理,我们先搭建一个SpringMVC的应用,将SpringMVC必备组件都配置到应用当中。对于SpringMVC的配置有XML和零XML方式。
二.XML的方式进行配置?
对于XML方式,主要有pom.xml,web.xml,applicationContext.xml,spring.xml几个配置文件,其中pom.xml引入所需要的的依赖和内置tomcat7插件;web.xml主要进行servlet相关的配置;applicationContext.xml是全局配置,可配置多个servlet配合监听器一起在web.xml中使用;spring.xml则是Spring容器的配置,如mvc驱动,bean声明等。
pom.xml:主要引入spring-webmvc和javax.servlet-api(3.0版本以上)依赖,fastJson的依赖用于消息转换器使用,tomcat依赖和插件配置则声明一个内置tomcat配置,启动时会按插件配置启动一个tomcat实例并发布这个web应用。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springmvc</groupId>
<artifactId>springmvc</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--springMVC依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--servlet依赖,注意要3.0以上才支持SPI规范-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
<!-- Tomcat7插件,在工程运行配置命令 tomcat7:run -->
<build>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>9090</port>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
<!--添加忽略war包检查标签,否则启动时会跳过非war导致无法发布这个应用,
设置忽略可以让tomcat7:run指令正常启动tomcat-->
<ignorePackaging>true</ignorePackaging>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml:主要进行DispatcherServlet和ContextLoaderListener的配置,同时引入全局配置contextConfigLocation加载
classpath:applicationContext.xml
在DispatcherServlet中设置<load-on-startup>1</load-on-startup>使得tomcat启动时马上执行DispatcherServlet的init方法,对
<init-param&