SpringMVC简介
# 1. 概述
定义
SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装;其主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端
学习SpringMVC我们先来回顾下现在web程序是如何做的,咱们现在web程序大都基于三层架构来实现。
浏览器发送一个请求给后端服务器,后端服务器现在是使用Servlet来接收请求和数据, 但如果所有的处理都交给Servlet来处理的话,所有的东西都耦合在一起,对后期的维护和扩展极为不利
- 将后端服务器Servlet拆分成三层,分别是
web
、service
和dao
- web层主要由servlet来处理,负责页面请求和数据的收集以及响应结果给前端
- service层主要负责业务逻辑的处理
- dao层主要负责数据的增删改查操作
💡PS: servlet处理请求和数据的时候,存在的问题是一个servlet只能处理一个请求
- 针对web层进行了优化,采用了MVC设计模式,将其设计为
controller
、view
和Model
- controller负责请求和数据的接收,接收后将其转发给service进行业务处理
- service根据需要会调用dao对数据进行增删改查
- dao把数据处理完后将结果交给service,service再交给controller
- controller根据需求组装成Model和View,Model和View组合起来生成页面转发给前端浏览器
- 这样做的好处就是controller可以处理多个请求,并对请求进行分发,执行不同的业务操作。
随着互联网的发展,上面的模式因为是同步调用,性能慢慢的跟不是需求,所以异步调用慢慢的走到了前台,是现在比较流行的一种处理方式。
- 因为是异步调用,所以后端不需要返回view视图,将其去除
- 前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成json格式进行返回
- SpringMVC主要负责的就是
- controller如何接收请求和数据
- 如何将请求和数据转发给业务层
- 如何将响应数据转换成json发回到前端
# 2. 工作流程
# 2.1 启动服务器初始化过程
- 服务器启动,执行继承AbstractDispatcherServletInitializer类的自定义类ServletConfig,初始化web容器
- 功能类似于以前的web.xml
AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
public class ServletConfig 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[]{"/"};
}
//设置post请求中文乱码过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
执行createServletApplicationContext方法,创建WebApplicationContext对象
- 该方法加载SpringMVC的配置类SpringMvcConfig来初始化SpringMVC的容器
加载SpringMvcConfig配置类
执行
@ComponentScan
加载对应的bean- 扫描指定包及其子包下所有类上的注解,如Controller类上的@Controller注解
加载UserController,每个@RequestMapping的名称对应一个具体的方法
- 此时就建立了
/save
和 save方法的对应关系
- 此时就建立了
执行getServletMappings方法,设定SpringMVC拦截请求的路径规则
/
代表所拦截请求的路径规则,只有被拦截后才能交给SpringMVC来处理请求
# 2.2 单次请求过程
- 发送请求
http://localhost/save
- web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
- 解析请求路径 /save
- 由/save匹配执行对应的方法save()
- 上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法
- 执行save()
- 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
# 3. bean加载控制
- config目录存入的是配置类,写过的配置类有:
- ServletContainersInitConfig
- SpringConfig
- SpringMvcConfig
- JdbcConfig
- MybatisConfig
- controller目录存放的是SpringMVC的controller类
- service目录存放的是service接口和实现类
- dao目录存放的是dao/Mapper接口
controller、service和dao这些类都需要被容器管理成bean对象,那么到底是该让SpringMVC加载还是让Spring加载呢?
- SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
- Spring控制的bean
- 业务bean(Service)
- 功能bean(DataSource,SqlSessionFactoryBeanMapperScannerConfigurer等)
通过在配置类中使用注解
@ComponentScan
,来设置不同配置文件扫描管理bean的范围
也可以通过excludeFilters排除一些无需扫描的类: 例如:修改Spring配置类,设定扫描范围为com.itheima,排除掉controller包中的bean
@Configuration
@ComponentScan(value="com.itheima",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
2
3
4
5
6
7
8
9
- excludeFilters属性:设置扫描加载bean时,排除的过滤规则
- type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
- ANNOTATION:按照注解排除