Version: Next
SpringMVC执行原理
- 虚线是需要我们编写实现的
- 实现是SpringMVC已经实现的
简要执行流程分析
- DispatcherServlet表示前端控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求
- 假设请求url为 http://localhost:8080/springmvc/hello
- http://localhost:8080为服务器域名,
http
为协议,localhost
为主机,8080
为端口 springmvc
表示部署在服务器上的web站点路径,即path
- hello表示控制器,如果是常见的GET请求方式,还可以携带参数,即
query
- url -> 请求位于服务器localhost:8080上的springmvc站点的hello控制器
- HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler
- HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello
- HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等
- HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
- Handler让具体的Controleer执行
- Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
- HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
- DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名
- 获取ModelAndView的数据
- 解析ModelAndView的视图名字
- 拼接视图名字(前后缀),找到对应的视图 /WEB-INF/jsp/
- 将数据渲染到这个视图上
- 视图解析器将解析的逻辑视图名传给DispatcherServlet
- DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图
- 最终视图呈现给用户
HandlerMapping
环境搭建
web.xml
- 配置DispatcherServlet
SpringMVC的核心,请求分发器,前端控制器
/
:只匹配所有的请求,不匹配jsp/*
:匹配所有的请求,包括jsp 视图解析器会拦截.jsp文件然后拼后缀.jsp,从而产生.jsp.jsp这样的东西,导致死循环
- 在DispatcherServlet里绑定SpringMVC的配置文件(一个Spring配置文件)
- 设置在服务器启动时启动
<!-- 配置DispatcherServlet--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 绑定SpringMVC配置文件(一个Spring配置文件)--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!-- 服务器已启动就启动--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>- 配置DispatcherServlet
SpringMVC的核心,请求分发器,前端控制器
springmvc-servlet.xml 真实开发不用配置以下两个东西,为了理解原理,配上 对应原理图,以下三个部件为SpringMVC的三大核心组件
处理器映射器
HandlerMapping
负责请求分发处理器适配器
HandlerAdapter
负责在DispatcherServlet和具体业务Controller之间进行适配视图解析器
ViewResolver
(不可省略) 负责模型视图渲染Spring原生、Thymeleaf、Freemarker
- 配置前缀
prefix
- 配置后缀
suffix
- 配置前缀
因为使用了
BeanNameUrlHandlerMapping
,所以需要配置一个带名字的bean- bean id:就起名为要解析的地址
- bean class: 指定哪个类来处理这个地址上的请求
<!-- 处理器映射器HandlerMapping--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!-- 处理器适配器HandlerAdapter--><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!-- 视图解析器ViewResolver--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><property name="prefix" value="WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>
Controller
public class HelloController implements Controller {public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {ModelAndView mv = new ModelAndView();//业务代码//虚拟返回值String result = "Result form Service";//视图跳转mv.addObject("msg", result);//去视图解析器,被视图解析器拼接为WEB-INF/jsp/test.jspmv.setViewName("test");return mv;}}
- 测试
- 记得在project structure -> Artifact中添加lib目录导入所有依赖包
- 记得将Tomcat中项目虚拟目录设置为
/