Version: Next

SpringMVC执行原理

image-20200407090504458

  • 虚线是需要我们编写实现的
  • 实现是SpringMVC已经实现的

简要执行流程分析

  1. 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控制器
  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler
  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等
  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
  6. Handler让具体的Controleer执行
  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名
    • 获取ModelAndView的数据
    • 解析ModelAndView的视图名字
    • 拼接视图名字(前后缀),找到对应的视图 /WEB-INF/jsp/
    • 将数据渲染到这个视图上
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet
  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图
  12. 最终视图呈现给用户

HandlerMapping

SpringMVC 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>
  • 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.jsp
    mv.setViewName("test");
    return mv;
    }
    }
  • 测试
    • 记得在project structure -> Artifact中添加lib目录导入所有依赖包
    • 记得将Tomcat中项目虚拟目录设置为/