Spring MVC 启动流程一览

        Spring MVC 是一种基于 Java 的 Web 框架,它提供了一种基于 MVC(Model-View-Controller)的架构模式,可以帮助开发者更轻松地构建Web应用程序。在本文中,我们将深入探讨 Spring MVC 的启动流程及初始化流程。

关键步骤

加载配置文件:Spring MVC的配置文件一般为 XML 格式,通过 ApplicationContext 来加载配置文件,获取相关的bean。

初始化 DispatcherServletDispatcherServlet 是整个 Spring MVC 的核心,它继承了 HttpServlet,实现了对 HTTP 请求的处理和响应。在初始化 DispatcherServlet 时,会调用其 init() 方法,并且为其设置一些参数,例如 SpringMVC 配置文件的位置等。

初始化 HandlerMapping:HandlerMapping负责将请求映射到相应的Controller上,DispatcherServlet在初始化时会初始化HandlerMapping,并将其注册到自己的属性中。

初始化 HandlerAdapter:HandlerAdapter 用于将请求对象转换成 ModelAndView 对象。在初始化时,DispatcherServlet 会根据 HandlerMapping 获取相应的 Controller,并生成相应的 HandlerAdapter。

初始化 ViewResolver:ViewResolver 用于将 ModelAndView 对象渲染成具体的视图(如JSP、HTML等)。在初始化时,DispatcherServlet 会根据 ViewResolver 的配置,生成相应的ViewResolver 对象。

启动 Spring MVC:DispatcherServlet 在初始化完成后,会监听HTTP请求,并将请求分发到相应的 Controller上 进行处理。处理完成后,将 ModelAndView 对象交给 ViewResolver 进行渲染。

Spring MVC初始化流程

加载配置文件

        Spring MVC 的配置文件一般为 XML 格式,可以在 web.xml 中配置。在配置文件中,需要声明 DispatcherServlet,并指定 Spring MVC 的配置文件位置。例如:

<servlet>
    <servlet-name>dispatcherServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring-mvc.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
servlet>

     这里配置了一个名为 dispatcherServlet 的 Servlet,并将其映射到 “/” 路径下。同时指定了 Spring MVC 的配置文件位置为 classpath:spring-mvc.xml。

初始化DispatcherServlet

        DispatcherServlet 是整个 Spring MVC 的核心,它继承了 HttpServlet,实现了对 HTTP 请求的处理和响应。在初始化DispatcherServlet 时,会调用其init()方法,并且为其设置一些参数,例如Spring MVC配置文件的位置等。具体的初始化过程可以参考DispatcherServlet的源码:

public void init(ServletConfig config) throws ServletException {
    // ...
    try {
        this.webApplicationContext = initWebApplicationContext();
        initFrameworkServlet();
    }
    catch (ServletException ex) {
        logger.error("Context initialization failed", ex);
        throw ex;
    }
    catch (RuntimeException ex) {
        logger.error("Context initialization failed", ex);
        throw ex;
    }
    // ...
}

protected WebApplicationContext initWebApplicationContext() {
    // ...
    // 加载配置文件,创建ApplicationContext
    ConfigurableWebApplicationContext wac = new XmlWebApplicationContext();
    wac.setServletContext(getServletContext());
    wac.setConfigLocation(getConfigLocation());
    // ...
    // 设置DispatcherServlet的父容器为ApplicationContext
    wac.setParent(applicationContext);
    // ...
    wac.refresh();
    // ...
    return wac;
}

        可以看出,DispatcherServlet 的初始化过程主要包括两个步骤:加载配置文件,创建 ApplicationContext,并设置 DispatcherServlet 的父容器为 ApplicationContext。

初始化HandlerMapping

        HandlerMapping 负责将请求映射到相应的 Controller 上,DispatcherServlet 在初始化时会初始化 HandlerMapping,并将其注册到自己的属性中。Spring MVC 提供了多种 HandlerMapping,包括:

BeanNameUrlHandlerMapping:将请求 URL 与 Handler Bean 的名称进行映射。

SimpleUrlHandlerMapping:将请求 URL 与 Handler 对象进行映射。

DefaultAnnotationHandlerMapping:将带有 @Controller 注解的类进行映射。

RequestMappingHandlerMapping:将带有 @RequestMapping 注解的方法进行映射。

        在初始化时,DispatcherServlet 会根据配置文件中的内容,生成相应的 HandlerMapping,并将其注册到自己的属性中。例如:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/hello">helloControllerprop>
        props>
    property>
bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

        这里配置了三个 HandlerMapping:BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping 和 RequestMappingHandlerMapping。

初始化HandlerAdapter

        HandlerAdapter 用于将请求对象转换成 ModelAndView 对象。在初始化时,DispatcherServlet 会根据 HandlerMapping 获取相应的Controller,并生成相应的 HandlerAdapter。Spring MVC 提供了多种 HandlerAdapter,包括:

SimpleControllerHandlerAdapter:用于处理实现了 Controller 接口的 Controller。

HttpRequestHandlerAdapter:用于处理实现了 HttpRequestHandler 接口的 Controller。

AnnotationMethodHandlerAdapter:用于处理带有 @RequestMapping注解的方法。

        在初始化时,DispatcherServlet 会根据 HandlerMapping 获取相应的 Controller,并生成相应的 HandlerAdapter。例如:

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

        这里配置了三个 HandlerAdapter:SimpleControllerHandlerAdapter、HttpRequestHandlerAdapter 和 AnnotationMethodHandlerAdapter。

初始化ViewResolver

        ViewResolver 用于将 ModelAndView 对象渲染成具体的视图(如JSP、HTML等)。在初始化时,DispatcherServlet 会根据 ViewResolver 的配置,生成相应的 ViewResolver 对象。Spring MVC 提供了多种 ViewResolver,包括:

InternalResourceViewResolver:将视图名称解析为 JSP 文件。

VelocityViewResolver:将视图名称解析为 Velocity 模板文件。

FreeMarkerViewResolver:将视图名称解析为 FreeMarker 模板文件。

TilesViewResolver:将视图名称解析为 Tiles 视图定义。

        在初始化时,DispatcherServlet 会根据 ViewResolver 的配置,生成相应的 ViewResolver 对象。例如:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
bean>

        这里配置了一个InternalResourceViewResolver 对象,它将视图名称解析为 JSP 文件。具体的解析过程可以参考 InternalResourceViewResolver 的源码:

public View resolveViewName(String viewName, Locale locale) throws Exception {
    // ...
    // 将视图名称解析为JSP文件
    String resourcePath = this.prefix + viewName + this.suffix;
    // ...
    return new InternalResourceView(resourcePath);
}

        可以看出,InternalResourceViewResolver 的 resolveViewName 方法将视图名称解析为 JSP 文件,并返回一个 InternalResourceView 对象。

启动Spring MVC

        在初始化完成后,DispatcherServlet 会监听 HTTP 请求,并将请求分发到相应的 Controller 上进行处理。处理完成后,将 ModelAndView 对象交给 ViewResolver 进行渲染。具体的处理流程可以参考 DispatcherServlet 的源码:

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // ...
    // 将请求分发给相应的Controller进行处理
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    mappedHandler = getHandler(processedRequest);
    if (mappedHandler == null || mappedHandler.getHandler() == null) {
        noHandlerFound(processedRequest, response);
        return;
    }
    // ...
    // 执行Controller的方法,处理请求
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    // ...
    // 将ModelAndView对象交给ViewResolver进行渲染
    render(mv, processedRequest, response);
    // ...
}

        可以看出,DispatcherServlet 的 doService 方法会将请求分发给相应的 Controller 进行处理,处理完成后,将 ModelAndView 对象交给 ViewResolver 进行渲染。

        今天我们先对启动流程有个初步的认识,在后面的篇章中,我们将详细了解每个步骤中对应的类型都有哪些功能。

你可能感兴趣的:(spring,mvc,java)