一、Spring MVC 功能
1. 基于注解的URL映射。
2. 表单参数映射。
3. 缓存处理。
4. 全局统一异常处理。
5. 拦截器的实现。
6. 下载处理。
1. Servlet 处理流程

1. 请求Servlet。
2. 处理业务逻辑。
3. 设置业务Model。
4. Forward Jsp Servlet。
5. Jsp Servlet 解析封装 html,并返回。
2. MVC 处理流程

1. URL映射。
2. 表单参数映射。
3. 调用目标Controller。
4. 数据模型映射。
5. 视图解析。
6. 异常处理。
二、Spring MVC 开始
1. pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
2. web.xml
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3. Controller
public class FastController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("[FastController].[handleRequest]");
ModelAndView modelAndView = new ModelAndView("/WEB-INF/page/fast_view.jsp");
modelAndView.addObject("name", "FastController");
return modelAndView;
}
}
4. fast_view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring MVC 开始</title>
</head>
<body>
登录人:${name}
</body>
</html>
5. spring-mvc.xml
<bean name="/fast.do" class="com.qs.spring_mvc_fast.controller.FastController"/>
三、Spring MVC 组件

1. DispatcherServlet 前端控制器
作为整个 Spring MVC 框架的核心组件,负责接收所有的 HTTP 请求;
并根据请求的 URL 将其分发给相应的处理程序。
它管理着整个请求处理的生命周期;
从接收请求、调用处理方法到返回响应,协调各个组件之间的工作。
2. HandlerMapping 处理器映射器
根据请求的 URL、HTTP 方法等信息,将请求映射到对应的处理器(Handler);
即具体的@Controller注解标注的方法或Controller接口的实现类中的方法。
支持多种映射方式,如基于 URL 路径的简单映射、基于注解的映射等;
以灵活地满足不同的业务需求。

1. 其为 MVC 中 URI 路径与 Controller 对象的映射。
2. DispatcherServlet 就是基于此组件,来寻找对应的 Controller。
3. 如果找不到就会报 `No mapping found for HTTP request with URI` 的异常。
1. HandlerMapping 的作用是通过 URI 找到对应的 Handler。
2. 但其方法 handlerMapping.getHandler(request) 并不会直接返回 Handler 对象。
3. 而是返回 HandlerExecutionChain 对象。
4. 再通过 handlerExecutionChain.getHandler() 返回最终的 Handler。
1. HandlerMapping、HandlerExecutionChain 接口方法

2. HandlerMapping 接口实现类

基于 IOC beanName 中"/"开头的 Bean 进行注册至映射。
基于手动配置 URI 与 Controller 映射。
基于 @RequestMapping 注解配置对应映射。
2. HandlerMapping 实现类
1. BeanNameUrlHandlerMapping Bean名称Url【默认】
1. BeanNameUrlHandlerMapping 类结构

BeanNameUrlHandlerMapping 实现上与 SimpleUrlHandlerMapping 一至;
唯一区别在于继承自 AbstractDetectingUrlHandlerMapping;
通过对应 detectHandlers 可以在无配置的情况下发现 URI 与 Handler 映射。
2. spring-mvc_BeanNameUrlHandlerMapping.xml
<bean name="/beanNameUrlHandlerMapping.do"
class="com.qs.spring_mvc_fast.controller.HandlerMapping.HandlerMappingController"/>
<bean id="/beanNameUrlHandlerMapping2.do"
class="com.qs.spring_mvc_fast.controller.HandlerAdapter.SimpleServletHandlerAdapterController"/>
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
<bean name="/beanNameUrlHandlerMapping3.do"
class="com.qs.spring_mvc_fast.controller.HandlerAdapter.HttpRequestHandlerAdapterController"/>
2. SimpleUrlHandlerMapping 简单Url
1. SimpleUrlHandlerMapping 类结构

1. org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
2. org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
3. org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
4. org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
`
/
/*
`
1. org.springframework.web.servlet.DispatcherServlet
2. org.springframework.web.servlet.DispatcherServlet
3. org.springframework.web.servlet.DispatcherServlet
4. org.springframework.web.servlet.handler.AbstractHandlerMapping
5. org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
6. org.springframework.web.util.UrlPathHelper
7. org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
8. org.springframework.web.servlet.handler.AbstractHandlerMapping
2. spring-mvc_SimpleUrlHandlerMapping.xml
<bean name="simpleUrlHandlerMapping"
class="com.qs.spring_mvc_fast.controller.HandlerMapping.HandlerMappingController"/>
<bean name="simpleUrlHandlerMapping2"
class="com.qs.spring_mvc_fast.controller.HandlerMapping.HandlerMappingController"/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="100"/>
<property name="urlMap">
<props>
<prop key="/simpleUrlHandlerMapping.do">simpleUrlHandlerMapping</prop>
<prop key="/simpleUrlHandlerMapping2.do">simpleUrlHandlerMapping2</prop>
<prop key="/simpleUrlHandlerMapping2-back.do">simpleUrlHandlerMapping2</prop>
</props>
</property>
</bean>
3. RequestMappingHandlerMapping @RequestMapping注解
1. spring-mvc2_RequestMappingHandlerMapping.xml
<context:component-scan base-package="com.qs.spring_mvc_fast.controller"/>
<mvc:annotation-driven/>
3. HandlerAdapter 处理器适配器
由于不同的处理器可能有不同的接口或实现方式;
HandlerAdapter 负责调用具体的处理器方法,并将请求参数等信息传递给处理器;
使 DispatcherServlet 能够统一地调用各种类型的处理器。
可以适配不同类型的处理器;
如基于注解的控制器、实现了特定接口的控制器等;
增强了框架的灵活性和扩展性。
当 IOC 实例化这些类之后;
DispatcherServlet 就会通过 dispatcherServlet.getHandlerAdapter(handler) 方法查找对应 Handler 适配器;
如果找不到就会报异常 `No adapter for handler`。
1. HandlerAdapter 接口方法

2. HandlerAdapter 接口实现类

标准控制器,返回 ModelAndView。
基于标准的 Servlet 处理。
业务自行处理请求,不需要通过 ModelAndView 转到视图。
基于 @RequestMapping 对应方法处理。
4. Handler 处理器
也称为控制器(Controller),是具体处理业务逻辑的组件。
通常使用@Controller注解标注,在其方法中编写处理 HTTP 请求的业务逻辑;
如调用服务层接口获取数据、进行数据处理等,并返回相应的结果或视图名称。

在 AbstractUrlHandlerMapping 类可以看到存储 Handler 的 Map 值类型是 Object;
意味着所有的类都可以做来 Handler 来使用。

1. Controller接口。
2. HttpRequestHandler接口。
3. HttpServlet接口。
4. @RequestMapping方法注解。
1. 一是用 instanceof 判断 Handler 类型然后调用相关方法。
2. 二是通过引入适配器,每个适配器实现对指定 Handler 的调用。
3. Spring 采用后者。
4. Handler 与 HandlerAdapter 对应关系
Handler类别 | 对应适配器 | 说明 |
---|
Controller接口 | SimpleControllerHandlerAdapter | 标准控制器,返回 ModelAndView。 |
HttpServlet接口 | SimpleServletHandlerAdapter | 基于标准的 Servlet 处理。 |
HttpRequestHandler接口 | HttpRequestHandlerAdapter | 业务自行处理请求,不需要通过 ModelAndView 转到视图。 |
HandlerMethod | RequestMappingHandlerAdapter | 基于 @RequestMapping 对应方法处理。 |
1. SimpleControllerHandlerAdapter 控制器适配器
2. SimpleServletHandlerAdapter Servlet适配器
public class SimpleServletHandlerAdapterController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("[SimpleServletHandlerAdapterController].[doGet]");
super.doGet(req, resp);
resp.getWriter().println("SimpleServletHandlerAdapterController");
}
}
<bean id="/simpleServletHandlerAdapter.do"
class="com.qs.spring_mvc_fast.controller.HandlerAdapter.SimpleServletHandlerAdapterController"/>
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
3. HttpRequestHandlerAdapter Http适配器
4. RequestMappingHandlerAdapter @RequestMapping适配器
5. ViewResolver 视图解析器
根据处理器返回的视图名称,选择并解析相应的视图;
如 JSP、Thymeleaf、FreeMarker 等视图技术,将模型数据填充到视图中,生成最终的 HTML 页面或其他响应内容返回给客户端。
可以配置多种视图解析策略,支持不同的视图技术和视图文件的存放位置等;
方便开发者根据项目需求进行选择和调整。
找到应的 Adapter 之后,就会基于适配器调用业务处理;
处理完业务方法之后,会返回一个 ModelAndView,再去查找对应的视图进行处理;
其在 dispatcherServlet.resolveViewName(viewName,model,..) 中遍历 viewResolvers 列表查找;
如果找不到就会报一个异常 `Could not resolve view with name`。
1. ViewResolver 实现类

1. BeanNameViewResolver Bean名称视图解析器
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/ViewResolver/"/>
<property name="suffix" value=".jsp"/>
<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/ViewResolver/"/>
<property name="suffix" value=".jsp"/>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
</bean>
6. ModelAndView 模型与视图
用于封装处理器处理请求后生成的模型数据和视图信息。
模型数据可以是各种 Java 对象,视图信息则包含视图名称等;
方便在处理器和视图解析器之间传递数据和视图相关的信息。
基于 viewResolver.resolveViewName(viewName,.) 获取对应 View;
来解析生成 html 并返回。
1. View 接口实现类

public class ViewX implements View {
@Override
public String getContentType() {
System.out.println("[ViewX].[getContentType]");
return null;
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("[ViewX].[render] model = " + model);
response.getWriter().print(String.format("ViewX:%s", model.get("name")));
}
}
<bean name="viewX" class="com.qs.spring_mvc_fast.controller.ModelAndView.ViewX"/>
7. 数据绑定与验证组件
将 HTTP 请求中的参数自动绑定到处理器方法的参数或 Java 对象中;
方便开发者获取和处理请求数据,减少了手动获取和转换请求参数的繁琐工作。
对绑定的数据进行合法性验证,如检查必填字段、数据格式等,确保数据的有效性和完整性。
通常与 Java Bean Validation 等验证框架集成使用。
8. HandlerInterceptor 拦截器
可以在请求处理的前后进行一些通用的操作,如权限验证、日志记录、性能监控等。
类似于 Servlet 中的过滤器,但更侧重于对请求处理过程的拦截和增强。
多个拦截器可以组成一个拦截器链,按照一定的顺序对请求进行处理;
并且可以根据需要灵活配置拦截器的执行顺序和作用范围。
与原生 Filter 区别在于 Filter 只能在业务执行前拦截;
而 HandlerInterceptor 可以在业务处理前、中、后进行处理。
1. preHandle()
2. postHandle()
3. afterCompletion()
org.springframework.web.servlet.DispatcherServlet
public class HandlerInterceptorX implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("[HandlerInterceptorX].[preHandle] handler = " + handler);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("[HandlerInterceptorX].[postHandle] handler = " + handler + ", modelAndView = " + modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("[HandlerInterceptorX].[afterCompletion] handler = " + handler + ", ex = " + ex);
}
}
<bean name="handlerInterceptor"
class="com.qs.spring_mvc_fast.controller.HandlerInterceptor.HandlerInterceptorX"/>
9. HandlerExceptionResolver 异常处理器
用于处理在请求处理过程中发生的各种异常情况,如业务异常、运行时异常等。
可以根据不同的异常类型进行针对性的处理,返回统一的错误页面或错误信息给客户端;
提高了系统的稳定性和用户体验。
1. DispatcherServlet 会调用 dispatcherServlet.processHandlerException(request,response,handler,ex) 方法;
2. 遍历 handlerExceptionResolvers 处理异常;
3. 处理完成之后返回 errorView 跳转到异常视图。
1. HandlerExceptionResolver 接口实现类

Spring mvc 默认异常处理。
用于解析带 @ResponseStatus 的自定义异常。
异常映射,将指定异常与错误页面相对应。
9. HandlerExceptionResolver 实现类
1. DefaultHandlerExceptionResolver 默认异常处理器
public class HandlerExceptionResolverX implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView("/WEB-INF/HandlerExceptionResolver/HandlerExceptionResolver.jsp");
if (ex instanceof IllegalArgumentException) {
modelAndView.addObject("errorType", "非法参数");
} else {
modelAndView.addObject("errorType", ex.getClass().getName());
}
modelAndView.addObject("message", ex.getMessage());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ex.printStackTrace(new PrintStream(outputStream, true));
modelAndView.addObject("stack", outputStream.toString());
return modelAndView;
}
}
<bean class="com.qs.spring_mvc_fast.controller.HandlerExceptionResolver.HandlerExceptionResolverX"/>
<bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver"/>
2. SimpleMappingExceptionResolver 简单的映射异常解析器
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="defaultStatusCode" value="500"/>
<property name="exceptionMappings">
<map>
<entry key="java.lang.RuntimeException" value="runtime_exception"/>
<entry key="java.lang.IllegalArgumentException" value="illegal_argument_exception"/>
</map>
</property>
</bean>
10. 本地化与国际化组件
支持根据客户端的语言偏好和地区设置,对应用中的文本信息进行本地化和国际化处理;
使应用能够以不同的语言和格式展示给用户。
通过配置资源文件,将不同语言和地区的文本信息进行统一管理;
方便在视图中引用和显示本地化的内容。
四、Spring MVC 执行流程

五、DispatchServlet 初始化流程
1. 创建 WebApplicationContext
1. org.springframework.web.servlet.HttpServletBean
2. org.springframework.web.servlet.FrameworkServlet
3. org.springframework.web.servlet.FrameworkServlet
4. org.springframework.web.servlet.FrameworkServlet
5. org.springframework.web.servlet.FrameworkServlet
6. org.springframework.context.support.AbstractApplicationContext
2. 基于策略模型加载各组件
六、@RequestMapping 注解
<context:component-scan base-package="com.qs.spring_mvc_fast.controller"/>
<mvc:annotation-driven/>
@Controller
@RequestMapping("anno")
public class RequestMappingController {
@RequestMapping("/handlerMethod.do")
public ModelAndView handlerMethod(String name) {
System.out.println("[RequestMappingController].[handlerMethod] name = " + name);
ModelAndView modelAndView = new ModelAndView("/WEB-INF/HandlerAdapter/HandlerAdapter.jsp");
modelAndView.addObject("name", "RequestMappingController");
return modelAndView;
}
}
1. 认识 NamespaceHandler 接口。
2. 查看 MvcNamespaceHandler。
3. 查看 AnnotationDrivenBeanDefinitionParser。
分别是 RequestMappingHandlerMapping 与 BeanNameUrlHandlerMapping 组件。
1. 实现结构

1. RequestMappingHandlerMapping
2. RequestMappingHandlerAdapter
3. InvocableHandlerMethod
`
1. HandlerMethodArgumentResolverComposite
2. ParameterNameDiscoverer
3. HandlerMethodReturnValueHandlerComposite
`
2. 执行流程
1. org.springframework.web.servlet.DispatcherServlet
2. org.springframework.web.servlet.handler.AbstractHandlerMapping
3. org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
4. org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry
1. org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
2. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
3. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
4. org.springframework.web.method.support.InvocableHandlerMethod
5. org.springframework.web.method.support.InvocableHandlerMethod