Spring MVC 入门
Spring MVC入门
Spring MVC概述
Spring MVC是基于Java的Web框架,用于开发基于Model-View-Controller(MVC)架构的Web应用程序。它提供了一种组织和管理Web应用程序的方式,将应用程序分为模型(Model)、视图(View)和控制器(Controller),以提高代码的可维护性、可扩展性和可测试性。
对于Spring MVC而言,其最大的特色是结构松散,比如几乎可以在Spring MVC中使用各类视图,包括json、jsp、xml、pdf等,所以它能够满足手机端、PC页面端和平板及物联网等各类请求。Spring MVC的核心在于其流程,这是使用Spring MVC的基础,Spring MVC是一种基于servlet的技术,它提供了核心控制器DispatcherServlet和相关的组件,并制定了松散的结构,以适合各种灵活的需要。

图注:Spring MVC核心组件关系图
核心工作流程
Spring MVC框架是围绕DispatcherServlet而工作的,所以这个类是其最为重要的类。它是一个Servlet,可以拦截HTTP发送过来的请求,具体工作流程如下:
- Servlet初始化时,Spring MVC会根据配置,获取配置信息,从而得到统一资源标识符和处理器之间的映射关系,同时为处理器加入拦截器,构成处理器的执行链,并初始化视图解析器等内容。
- 当一个请求到来时,DispatcherServlet首先通过请求和事先解析好的HandlerMapping配置,找到相应的Handler(处理器),准备运行处理器和拦截器组成的执行链。
- 运行处理器需要对应的环境,通过处理器适配器HandlerAdapter,运行对应的处理器和拦截器(处理器包含了控制器的内容和其他增强功能)。
- 处理器返回模型和视图(ModelAndView)给DispatcherServlet后,DispatcherServlet会把对应的视图信息传递给视图解析器。
- 视图解析器定位视图,将数据模型渲染到视图中,响应用户的请求。
Spring MVC环境搭建
添加相关依赖
plugins {
id 'war'
id 'java'
}
dependencies {
implementation 'org.springframework:spring-webmvc:7.0.2'
}
容器关系说明

图注:Spring MVC中WebApplicationContext容器层级关系图
在Spring MVC官方文档中可知,两个容器存在父子关系,具体说明如下:
- RootContext会被注入到ServletContext的parentBeanFactory中。
- Spring MVC的容器ServletContext中如果没有bean,则委派RootContext中去查找,即ServletContext中可以访问RootContext中的bean,反过来则不行。
- 根WebApplicationContext(Root WebApplicationContext)通常包含基础设施bean,如需要在多个Servlet实例之间共享的数据存储库和业务服务。
- Servlet特定的子WebApplicationContext通常包含给定Servlet的本地bean,如控制器、视图解析器和其他与Web相关的bean,根容器中的bean会被有效继承,且可在子容器中重写(重新声明)。
配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置ContextLoaderListener用于初始化Spring IoC容器(root WebApplicationContext) -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置spring IoC配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-root.xml</param-value>
</context-param>
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--如果没有指定加载文件,会从/WEB-INF/下去加载以 servlet-name,即dispatcherServlet的xml文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
web.xml配置内容说明
- 系统变量contextConfigLocation的配置:它会告诉Spring MVC其Spring IoC的配置文件在哪里,Spring会找到这些配置文件并加载。多个配置文件可使用逗号分割,支持正则式模糊匹配,默认值为
/WEB-INF/applicationContext.xml。 - ContextLoaderListener:实现了ServletContextListener接口,在Web工程初始化之前完成Spring IoC容器的初始化,在Web工程关闭时释放Spring IoC容器的资源。
- DispatcherServlet配置:配置了在服务器启动时对其进行初始化,且拦截以后缀
do结尾的请求,所有以do结尾的请求都会被其拦截。
配置spring-root.xml(对应Root WebApplicationContext容器)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
配置说明
配置组件自动扫描,对以@Controller标注的组件进行排除(Root WebApplicationContext通常包含基础架构bean)。
配置spring-mvc.xml(Spring MVC相关配置)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.controller" />
<!--
以注解驱动spring mvc
内部已经包含针对注解的HandlerMapping和HandlerAdapter
-->
<mvc:annotation-driven/>
<!-- 配置视图解析器:jstl + el解析jsp视图 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 逻辑视图名的前缀 -->
<property name="prefix" value="/WEB-INF/pages/"/>
<!-- 逻辑视图名的后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
配置说明
<mvc:annotation-driven/>:表示使用注解驱动Spring MVC,内部已包含针对注解的HandlerMapping和HandlerAdapter。- 组件扫描:扫描
com.controller包,加载对应的控制器。 - 视图解析器配置:定义了逻辑视图名的前缀(
/WEB-INF/pages/)和后缀(.jsp),视图会到Web工程的/WEB-INF/pages文件夹中找到对应的jsp文件作为响应视图。
开发控制器(Controller)
package com.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class WelcomeController {
/**
* 处理器
* @return 模型和视图
* @RequestMapping: url(/mvc/index.do)和处理器映射
*/
@RequestMapping("/mvc/index.do")
public ModelAndView index(){
//模型(共享数据,作用域范围为request)和视图
ModelAndView mv = new ModelAndView();
mv.addObject("message","hello spring mvc");//request.setAttribute("message","hello spring mvc");
//绑定逻辑视图(默认是forward),指定了逻辑视图名,DispatcherServlet选择视图解析器解析视图,根据逻辑视图名找到view进行渲染
mv.setViewName("index");//request.getRequestDispatcher(prefix + viewName + suffix).forward(request,response); //WEB-INF/pages/index.jsp
//返回给DispatcherServlet
return mv;
}
}
控制器说明
@Controller注解:标识该类为控制器,Spring MVC扫描时会将其作为控制器加载。@RequestMapping("/mvc/index.do"):指定对应的请求URI,Spring MVC初始化时会解析该信息并存储,形成HandlerMapping,请求到来时通过该信息找到对应的控制器提供服务。- 返回值ModelAndView:方法中指定视图名称为
index,结合视图解析器的前缀和后缀,最终会寻找/WEB-INF/pages/index.jsp作为响应视图,并将message数据传递到视图中。
编写视图页面(index.jsp)
<%--
Created by IntelliJ IDEA.
User: Jing61
Date: 2025/12/23
Time: 09:54
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${message}
</body>
</html>
控制器请求处理流程示意图

图注:Spring MVC控制器请求处理流程(包含注解解析、处理器映射、适配器调用、视图解析等环节)
Spring MVC启动过程
ServletContext初始化
Web容器(比如tomcat、jboss、weblogic等)启动时,会为每个Web应用程序创建一个ServletContext对象,它代表当前Web应用的上下文。一个Web应用(即一个Web工程)有且仅创建一个ServletContext,Web中的所有Servlet共享该对象,可通过ServletContext实现Servlet之间的通讯。在继承自HttpServlet的类中,可通过this.getServletContext获取ServletContext对象。
根上下文(Root WebApplicationContext)初始化
在Web程序中使用Spring时,需配置ContextLoaderListener监听器:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- Web容器启动时会触发容器初始化事件,ContextLoaderListener监听到该事件后,其
contextInitialized方法会被调用。 - 在该方法中,Spring会初始化一个根上下文(WebApplicationContext,继承自ApplicationContext接口,实际实现类为XmlWebApplicationContext),即Spring的IoC容器。
- 根上下文对应的Bean定义配置由web.xml中的
context-param标签指定。 - 根上下文初始化完毕后,Spring以
WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于后续获取。
DispatcherServlet上下文初始化
- ContextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet(可配置多个,以DispatcherServlet为例)。
- DispatcherServlet是标准的前端控制器,用于转发、匹配、处理每个Servlet请求。
- DispatcherServlet初始化时会建立自己的IoC上下文(持有Spring MVC相关的bean),建立时会通过
WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE从ServletContext中获取根上下文,作为自己上下文的parent上下文。 - 之后初始化自身持有的上下文,核心工作包括初始化处理器映射、视图解析器等(可在
initStrategies方法中查看详细逻辑),其默认实现类也是XmlWebApplicationContext。 - 初始化完毕后,Spring以与Servlet名字相关的属性为Key(具体转换规则可查看源码),将该上下文也存储到ServletContext中。
- 最终每个Servlet持有自己的上下文(独立的bean空间),同时所有Servlet共享根上下文定义的bean。

浙公网安备 33010602011771号