Spring MVC-简单使用
零、本文纲要
- 一、Spring MVC基础
1、认识Spring MVC
2、Spring MVC快速入门
3、AbstractDispatcherServletInitializer抽象类
4、涉及注解
5、流程解析 - 二、Bean加载控制
1、情形分析
2、Bean加载控制
3、AbstractAnnotationConfigDispatcherServletInitializer抽象类
一、Spring MVC基础
1、认识Spring MVC
SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装。
SpringMVC是处于Web层的框架,所以其主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端,所以如何处理请求和响应是SpringMVC中非常重要的一块内容。
浏览器(发送请求) → 服务器(Servlet接收请求和数据)
- ① Web程序-三层架构
服务器Servlet
拆分成三层:Web、Service、Dao;
a、Web
:由servlet来处理,负责页面请求和数据的收集以及响应结果给前端;
b、Service
:负责业务逻辑的处理;
c、Dao
:负责数据的增删改查操作。
存在的问题:一个servlet只能处理一个请求。
- ② Web程序-MVC架构
Web
:设计为Controller
、View
和Model
;
a、Controller
:负责请求和数据的接收,接收后将其转发给Service进行业务处理;
b、Service
:根据需要会调用dao对数据进行增删改查;
c、Dao
:把数据处理完后将结果交给Service,Service再交给Controller;
d、Controller
:根据需求组装成Model
和View
,Model和View组合起来生成页面转发给前端浏览器;
好处:一个Controller可以处理多个请求,并对请求进行分发,执行不同的业务操作;
存在的问题:模式为同步调用。
- ③ Web程序-Spring MVC架构
View
:交由HTML、CSS、Vue、ElementUI等处理;
Model
:一般转换成JSON格式返回;
a、Controller
:接收请求和数据,将请求和数据转发给业务层;
b、Service
:根据需要会调用dao对数据进行增删改查;
c、Dao
:把数据处理完后将结果交给Service,Service再交给Controller;
d、Controller
:将响应数据转换成JSON
发回到前端。
好处:异步调用、性能更优;使用简单、灵活性强。
2、Spring MVC快速入门
- ① 引入依赖
javax.servlet-api:servlet所需依赖,provided在编译和测试的时候用,避免运行时与tomcat中的冲突;
spring-webmvc:spring-web和mvc依赖;
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
tomcat插件
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
- ② 创建Spring MVC配置类
@Configuration
@ComponentScan("com.stone.controller")
public class SpringMvcConfig {
}
- ③ 创建Controller
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody // 没有此注解,则会依据寻找页面;有此注解直接返回字符串
public void save(){
System.out.println("User save ...");
return "{'info':'springmvc'}";
}
}
- ④ 创建Servlet容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"}; // 表示所有请求路径由springmvc控制器处理
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
3、AbstractDispatcherServletInitializer抽象类
AbstractDispatcherServletInitializer类
是SpringMVC提供的快速初始化Web3.0容器
的抽象类。

- ① createServletApplicationContext方法
createServletApplicationContext用来加载SpringMVC环境。
创建Servlet容器时,加载SpringMVC对应的Bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServletContext范围,即整个Web容器范围。
SpringMVC对应的Bean:一般指我们Controller层
的Bean。
- ② getServletMappings方法
设定SpringMVC对应的请求映射路径,即SpringMVC拦截处理哪些请求。
- ③ createRootApplicationContext方法
createRootApplicationContext用来加载Spring环境。
如果创建Servlet容器时需要加载非SpringMVC对应的Bean,使用当前方法进行,使用方式和createServletApplicationContext相同。
非SpringMVC对应的Bean:一般指我们Service层
、Dao层
等的Bean。
4、涉及注解
- ① @Controller
用于类上,代表SpringMVC控制器类,设定SpringMVC的核心控制器Bean;
- ② @RequestMapping
用于类或者方法上,设置当前控制器方法请求访问路径;
- ③ @ResponseBody
用于类或者方法上,设置当前控制器方法响应内容为当前返回值,无需解析。
5、流程解析
- ① 容器关系
Web容器 → ServletContext → WebApplicationContext → *Controller → /path → path()
- ② 服务器初始化过程
Ⅰ 服务器启动,执行ServletContainersInitConfig类,初始化web容器(类似于web.xml);
Ⅱ 执行createServletApplicationContext方法,创建了WebApplicationContext对象;
Ⅲ 加载SpringMvcConfig配置类,初始化SpringMVC的容器;
Ⅳ 执行@ComponentScan加载对应的Bean(如此处的@Controller);
Ⅴ 建立@RequestMapping路径与Controller类方法关系;
Ⅵ 执行getServletMappings方法,设定SpringMVC拦截请求的路径规则。
注意:快速入门案例中我们没有给createRootApplicationContext方法配置Spring的核心容器,所以我们此处省略其步骤。
- ③ 请求解析过程
Ⅰ 发送请求http://localhost:80/save
;
Ⅱ Web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理;
Ⅲ 解析请求路径/save
;
Ⅳ 匹配到save方法;
Ⅴ 执行save方法;
Ⅵ 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方。
注意:我们此处省略了DispatcherServlet前端控制器这些内容的深入说明。
二、Bean加载控制
1、情形分析
- ① 基础项目目录结构
Ⅰ config目录
:ServletContainersInitConfig、SpringConfig、SpringMvcConfig、JdbcConfig、MybatisConfig等;
Ⅱ controller目录
:存放的是SpringMVC的Controller类;
Ⅲ service目录
:存放的是Service接口和实现类;
Ⅳ dao目录
:存放的是Dao/Mapper接口;
等等。
- ② 存在情形
Controller、Service和Dao这些类都需要被容器管理成Bean对象,其中:
SpringMVC容器
需要管理表现层的Bean,对应Controller;
Spring容器
则需要管理其他Bean,避免错误加载到SpringMVC管理的Bean。
所以,我们需要对Bean加载进行控制。
2、Bean加载控制
- 基础配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 与快速入门案例不同的地方,此处添加了Spring容器创建的实现
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
@Configuration
@ComponentScan("com.stone.controller")
public class SpringMvcConfig {
}
@Configuration
@ComponentScan("com.stone") // 此时即存在错误加载的情况
public class SpringConfig {
}
- ① 方式一:设定扫描范围为精准范围
此种设置下我们精准扫描service、dao包,可以避免扫描到controller包,如下:
@Configuration
@ComponentScan({"com.stone.service","com.stone.dao"})
public class SpringConfig {
}
- ② 方式二:排除掉controller包中的Bean
使用@ComponentScan的属性设置,进而避免扫描到controller包,如下:
@Configuration
@ComponentScan(value="com.stone",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
Ⅰ excludeFilters属性:设置扫描加载bean时,排除的过滤规则;
Ⅱ type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除,其分类如下:
- ANNOTATION:按照注解排除(重点)
- ASSIGNABLE_TYPE:按照指定的类型过滤;
- ASPECTJ:按照Aspectj表达式排除(基本上不会用);
- REGEX:按照正则表达式排除;
- CUSTOM:按照自定义规则排除。
Ⅲ classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean。
3、AbstractAnnotationConfigDispatcherServletInitializer抽象类
- ① AbstractDispatcherServletInitializer抽象类
在Servlet容器初始化的相关配置中,我们实现AbstractDispatcherServletInitializer可以帮助我们设置SpringMVC、Spring容器,但是需要我们手动创建AnnotationConfigWebApplicationContext对象来设置,如下:
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
- ② AbstractAnnotationConfigDispatcherServletInitializer抽象类
该抽象类可以帮我们简化代码,如下:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// 配置Spring容器
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
// 配置SpringMVC容器
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
// 配置SpringMVC管理的请求路径,此处"/"表示管理所有请求
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
三、结尾
以上即为Spring MVC-简单使用的全部内容,感谢阅读。