Spring MVC

  1. 前言
  2. Spring MVC
  3. 源码分析
    1. DispatcherServlet
      1. 过程
  4. Spring MVC 如何以统一的方式,将数据纳入不同的视图并显示?

前言

Spring 是啥?

MVC 是啥?

Spring MVC 是一个基于 Spring 的 Web 框架.

在 Java Web 中,需要自己实现 HttpServlet,Spring MVC 对 平时用到的 Servlet 进行了一层封装.

Spring MVC

下面以一个完整的后端渲染流程大致说明一下.

原文 : 通过项目逐步深入了解Spring MVC(一)

在前后端分离项目中,无需 ModelAndView,直接返回 json 数据.

  1. DispatcherServlet(前端控制器) 接受所有的 Web 请求.

  2. 前端控制器请求 HandlerMapping(处理器映射器) 查找 Handler.(Handler 也就是 Controller 层)

    可根据 xml 配置,注解查找.(包括URL, Http方法, 请求报文头和请求参数 Cookie 等)

  3. HandlerMapping 向 DispatcherServlet 返回 Handler.

  4. DispatcherServlet 调用 HandlerAdapter(处理器适配器) 去执行 Handler.

  5. HandlerAdapter 执行 Handler.

  6. Handler 执行完成返回 ModelAndView 给 HandlerAdapter.

  7. HandlerAdapter 向 DispatcherServlet 返回 ModelAndView.

    ModelAndView 是 Spring MVC 的一个底层对象,包括 Model 和 View.

  8. DIspatcherServlet 请求 ViewResolver(视图解析器) 去进行视图解析.

    根据逻辑视图名解析成真正的视图

  9. ViewResolver 向 DispatcherServlet 返回 View

    View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

  10. DispatcherServlet 进行视图渲染

    视图渲染将模型数据(在 ModelAndView 中)填充到 request 域

    这一层就是 jsp,Thymeleaf 页面开发吧?

  11. DispatcherServlet 向用户相应结果

源码分析

DispatcherServlet

DispatcherServlet 的继承链 :

DispatcherServlet –> FrameworkServlet –> HttpServletBean –> HttpServlet

DispatcherServlet 其实是 HttpServlet 的子类.本质上也是一个 Servlet.

详情可见 : HttpServlet

大概介绍一下,Java EE 开发时,会继承 HttpServlet,实现里面的 doGet(),doPost() 等方法来相应 Http 请求.

public class Login extends javax.servlet.http.HttpServlet{
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // ... 
 }
}

Spring MVC 把这种细节屏蔽了.

看构造方法,

public DispatcherServlet(WebApplicationContext webApplicationContext) {
        super(webApplicationContext);
        setDispatchOptionsRequest(true);
    }

这里传入了一个 WebApplicationContext.

看 : Spring 启动流程

ApplicationContext 是 Spring IOC 的容器(也称 上下文),WebApplicationContext 继承自 ApplicationContext,为 Spring MVC 提供上下文环境.使之在 Web 环境可以访问 Spring 的上下文.有了这个,相应就可以通过 Spring 来管理 Bean 之类的啦…

通过 WebApplicationContext,可以访问 :

  1. ServletContext

    Web 服务器提供

  2. request, session, globalsession

  3. HttpServletRequest

    服务器获取客户端数据

  4. HttpServletResponse

    服务器向客户端传递数据

至于 WebApplicationContext 的创建,则由 Spring 来完成.

在一个 Spring MVC 项目中,通过在 web.xml 中配置 :

<listener>
        <description>spring listener</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

ContextLoaderListener 指定 Web 应用程序启动时载入 IOC 容器.

// todo 具体怎么加载呢?

过程

SpringMVC源码分析系列-精简

// spring-webmvc
// org.springframework.web.servlet.DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ...
    try {
        ModelAndView mv = null;
        Exception dispatchException = null;
        try {
            processedRequest = checkMultipart(request);
            multipartRequestParsed = (processedRequest != request);
            //1.调用handlerMapping获取handlerChain
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null || mappedHandler.getHandler() == null) {
                noHandlerFound(processedRequest, response);
                return;
            }
            // 2.获取支持该handler解析的HandlerAdapter
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
            ...
            // 3.使用HandlerAdapter完成handler处理
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
            if (asyncManager.isConcurrentHandlingStarted()) {
                return;
            }
            // 4.视图处理(页面渲染)
            applyDefaultViewName(request, mv);
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        }
        catch (Exception ex) {
            dispatchException = ex;
        }
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    ...
}

对应上文 Spring MVC 的 11 个步骤…

// todo [先到此]

Spring MVC 如何以统一的方式,将数据纳入不同的视图并显示?

服务端渲染才会考虑这一点.

底层(Servlet)是 HttpServletResponse.

将视图数据通过 HttpServletResponse 输出前,借助不同的视图技术 API,结合数据和模板文件,生成最终结果.

文章标题:Spring MVC

文章字数:847

本文作者:禾七

发布时间:2019-04-06, 00:00:00

最后更新:2019-12-18, 15:46:53

原始链接:https://leay.net/2019/04/06/Spring-MVC/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录