走向自动装配 Spring Web MVC 篇|第一章-传统Spring Web MVC
文章目录
文章说明
由浅入深的了解 Spring Web MVC 的发展过程,从 Servlet 技术如何一步一步到 Spring Boot 中实现自动装配的 Spring Web MVC 。
- 第一章 - 传统 Spring Web MVC
- 第二章 - 注解驱动 Spring Web MVC
- 第三章 - 自动装配 Spring Web MVC
项目环境
- jdk 1.8
- Spring Boot 2.0.2.RELEASE
- github 地址:https://github.com/huajiexiewenfeng/deep-in-spring-boot
- 本章模块:spring-web-mvc
1.Servlet 简单回顾
1.1 Servlet 流程图
1.2 Servlet 特点
-
请求/响应式(Request/Response)
-
屏蔽网络通讯的细节
-
完整生命周期
1.3 Servlet 职责
- 处理请求
- 资源管理
- 视图渲染
2.Spring Web MVC
2.1 J2EE 核心模式-前端控制器(Front Controller)
http://www.corej2eepatterns.com/FrontController.htm
实现:Spring Web MVC DispatcherServlet
下面是 Spring Web MVC 文档 1.0.0 版本相关内容链接,后续的版本虽然没有再提到 Front Controller,但是只是描述上的不同,核心还是前端控制器模式。
https://docs.spring.io/spring/docs/1.0.0/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html
public class DispatcherServlet extends FrameworkServlet
Concrete front controller for use within the web MVC framework. Dispatches to registered handlers for processing a web request.
翻译:在 web MVC 框架中,我们非常熟悉的 DispatcherServlet 是一个具体的前端控制器实现,分派给已注册的处理器来处理 web 请求。
2.2 Spring Web MVC 架构
可以看到 Spring Web MVC 的架构就是在 前端控制器 基础之上构建的,使用的是 Servlet 引擎,可以说 Spring Web MVC 其实就是 Servelt 技术。
- DispatcherServlet-> Front controller
- Controller -> ApplicationCotroller
- model -> Command/View
- View template -> ServletFront/JSPFront
3.配置 Spring Web MVC
通过一个简单的应用来回顾早期传统的 Spring Web MVC
3.1 新建一个 maven 项目
pom.xml 依赖如下
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>deep-in-spring-boot</artifactId>
<groupId>com.huajie</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-web-mvc</artifactId>
<packaging>war</packaging>
<dependencies>
<!-- Spring Web MVC 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- servlet 3.1 API 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
</project>
3.2 实现 Controller
@Controller
public class HelloWorldController {
@RequestMapping("")
public String index(){
return "index";
}
}
3.3 配置 Web MVC 组件
新建 webapp/WEB_INF 目录,新建 app-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.huajie.deepinspringboot.web"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3.4 配置 DispatcherServlet
webapp/WEB_INF 目录下新建 web.xml
<web-app>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.5 新建 jsp 页面
目录结构:
webapp
- WEB-INF
- jsp
- index.jsp
- app-context.xml
- web.xml
- jsp
index.jsp:
hello,world
pom 文件配置 tomcat 插件
- 这个插件可以将项目打包成一个可执行 jar 包,内部嵌入 tomcat 的 web 容器
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
<configuration>
<!-- ServletContext path -->
<path>/</path>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3.6 打包
G:\workspace\deep-in-spring-boot\spring-web-mvc\>mvn -Dmaven.test.skip -U clean package
3.7 启动
G:\workspace\deep-in-spring-boot\spring-web-mvc\target>java -jar spring-web-mvc-0.0.1-SNAPSHOT-war-exec.jar
浏览器输入 http://127.0.0.1:8080/
4.调用流程
4.1 Web MVC 核心组件
组件 Bean 类型 | 说明 |
---|---|
HandlerMapping | 映射请求(Request)到处理器(Handler)加上其关联的拦截器(HandlerInterceptor)列表,其映射关系基于不同的 HandlerMapping 实现的一些标准细节。其中两种主要 HandlerMapping 实现, RequestMappingHandlerMapping 支持标注 @RequestMapping 的方法, SimpleUrlHandlerMapping 维护精确的 URI 路径与处理器的映射 |
HandlerAdapter | 帮助 DispatcherServlet 调用请求处理器(Handler),无需关注其中实际的调用细节。比如,调用注解实现的 Controller 需要解析其关联的注解. HandlerAdapter 的主要目的是为了屏蔽与 DispatcherServlet 之间的诸多细节。 |
HandlerExceptionResolver | 解析异常,可能策略是将异常处理映射到其他处理器(Handlers) 、或到某个 HTML 错误页面,或者其他。 |
ViewResolver | 从处理器(Handler)返回字符类型的逻辑视图名称解析出实际的 View 对象,该对象将渲染后的内容输出到 HTTP 响应中。 |
LocaleResolver LocateContextResolver | 从客户端解析出 Locale ,为其实现国际化视图。 |
MultipartResolver | 解析多部分请求(如 Web 浏览器文件上传)的抽象实现 |
4.2 调用流程图
4.3 源码调试
增加调试接口启动
G:\workspace\deep-in-spring-boot\spring-web-mvc\target>java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 spring-web-mvc-0.0.1-SNAPSHOT-war-exec.jar
点击 Idea debug 会显示连接成功,然后就可以调试了
我们在每一步中打上断点进行调试,浏览器输入 http://127.0.0.1:8080/
1.DispatcherServlet#doDispatch 949 行
2.DispatcherServlet#getHandler 1183 行
此时只有一个对象就是我们 app-context.xml 中配置的对象,继续往下,通过 getHandler 方法可以拿到 handler 对象,这个对象中的方法就是我们的 index() 方法
3.org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter 1224 行
4.我们 HelloWorldController#index 方法中
5.DispatcherServlet#resolveViewName 1365 行
6.最后返回浏览器页面 hello,world 信息
5.参考
- 慕课网-小马哥《Spring Boot2.0深度实践之核心技术篇》