SpringMVC源码学习
MVC由来
- 早期的mvc模型,JSP既负责展示数据,也负责处理数据
- 所有代码逻辑编写在JSP中
- 代码重用性低,维护难度高,后来被淘汰
- 后期进行改良或,JSP纯粹负责展示数据
- 处理请求交给控制器,也就是Servlet来处理
- 控制器只负责前端简单逻辑处理
- 负责逻辑依然靠后端JavaBean实现
SpringMVC执行过程分析
三大核心组件
1. 处理器映射器
- spring3.1后引入
- 配置方式:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappin gHandlerMapping"/>
or:
<mvc:annotation‐driven></mvc:annotation‐driven>
2. 处理器适配器
- 可以理解为对控制器的抽象
- 将控制器的公共功能都定义在适配器中实现
- 适配器类型有多种
- 不同handle类型也对应不同的处理器适配器类型
Handler类别 对应适配器 描述
Controller SimpleControllerHandlerAdapter 标准控制器,返回ModelAndView
HttpRequestHandler HttpRequestHandlerAdapter 业务自行处理 请求,不需要通过 modelAndView 转到视图
Servlet SimpleServletHandlerAdapter 基于标准的servlet 处理
HandlerMethod RequestMappingHandlerAdapter 基于@requestMapping对应方法处理
3. 视图解析器
- 作用是渲染模型数据,将模型里的数据以某种形式呈现给客户
- 视图模型与具体实现技术进行了解耦
- 顶层有一个高度抽象的View接口
- View接口是无状态化的,也就说每个请求都会产生一个view实例,因此不存在线程安全问题
- 常用视图类型有
- URL视图(JSP/Freemarker)
- 文档类型视图(PDF/EXCEL)
- JSON视图(JACKSON/FastJSON)
- XML视图(xml)
- 可理解为其作用是将逻辑视图转为物理视图
控制器返回参数三种类型
- String,通常为view路径或重定向路径
- void,直接使用原始SerlvetAPI进行转发或重定向
- ModelAndView,实际说返回String时,也会创建mav
请求参数的实现原理
- 利用原生ServletAPI配合反射机制而实现
- RequestParam/RequestBody/PathVariable
拦截器的实现原理
- 一句话,就是利用AOP的机制
- 自定义拦截器的三个方法:
- preHandler 控制器方法执行之前执行
- postHandler 控制方法执行之后,视图创建之前
- afterCompletion 视图创建之后,展示到浏览器之前
- afterCompletion无法控制相应结果,一般用于做一些清理操作
Spring整合SpringMVC
- 注意SpringIOC容器不应该扫描SpringMVC中的bean
- 同样,SpringMVC也不要扫描SpringIOC中的bean
- 否则bean会被创建2次
- 为啥?因为Spring容器与SpringMVC容器是父子关系
- MVC容器是Spring的子容器,因此MVC中的bean可引用Spring中的bean
- 而Spring中的Bean无法引用MVC容器中的bean
- 可以试试在Service中注入Controller看看
手写SpringMVC思路
- 创建准备自定义注解,准备SpringMVC核心配置文件
- 编写前端控制器:创建一个Servlet,在web.xml声明该总控
- 创建Spring容器,通过DOM4J解析SpringMVC的xml文件
- 扫描控制器及service,将其放入容器中
- 实现容器中对象的注入,将服务层对象注入到控制层
- 建立请求地址与控制器方法之间的映射关系
- 接收用户请求并进行分发
- 处理用户请求参数
- 控制器方法调用,并处理不同返回值数据