SpringMVC概述
SpringMVC 技术与Servlet技术功能等同,均属于web层开发技术,是一种基于Java实现MVC模型的轻量级Web框架、
SpringMVC的优点:
- 使用简单,开发便捷
- 灵活性强
MVC:模型(Mode),视图(View),控制器(Controller)
- 是 一种软件设计规范
- 是将业务逻辑,数据显示分离的方法来组织代码
- MVC主要作用就是降低了视图与业务逻辑的双向耦合
SpringMVC入门案例
1.使用SpringMVC技术需要导入SpringMVC的依赖与Servlet的依赖
Servlet依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
SpringMVC依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency>
2.创建SpringMVC的控制器类(等同于Servlet功能)
- 使用@Controller注解定义bean
- 使用@RequestMapping注解设置当前操作的访问路径
- 使用@ResponseBody设置当前操作的返回类型
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("User save");
return "{'module':'Spring MVC '}";
}
}
3.添加一个SpringMVC的配置类,加载对应的bean
//创建SpringMVC 的配置文件,加载controller包下对应的bean
@Configuration
@ComponentScan("com.itshicha.controller")
public class SpringMvcConfig {
}
4.添加一个Servlet的配置类,加载SpringMVC环境,并设置SpringMVC技术处理请求
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[0];
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
这个Servlet的配置类是必须继承AbstractDispatcherServletInitializer这个类并重写其三个方法
而且,由于这个类的大部分代码很固定,通常可以继承AbstractAnnotationConfigDispatcherServletInitializer这个类来达到简化开发的效果
只需要在对应方法填入对应的配置类就好
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
下面是对未简化的Servlet配置类的解析
- createServletApplicationContext()方法是用来加载SpringMVC的配置的,该方法需要写获取SpringMVC容器相关的代码例如
protected WebApplicationContext createServletApplicationContext() { //获取SpringMVC的容器 AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); //让SpringMVC容器扫描到SpringMVC配置类 ctx.register(SpringMvcConfig.class); return ctx; }
- getServletMappings()方法是设置那些请求归属SpringMVC处理的
-
@Override protected String[] getServletMappings() { return new String[]{"/"}; }
- createRootApplicationContext()方法是加载Spring配置的
入门案例工作流程分析
启动服务器初始化过程
- 服务器启动,执行ServletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建AnnotationConfigWebApplicationContext()对象
- 加载SpringMvcConfig
- 执行@ComponentScan加载对应的bean
- 加载UserController,每个@RequestMapping的名称都对应一个具体方法
- 执行getServletMappings()方法,设置所有的请求都通过SpringMVC来执行
单次请求过程
- 发送localhost:8080/save请求
- web容器接收到请求,发现是经过SpringMVC,将请求交给SpringMVC
- 解析请求路径/save
- 匹配执行对应的save方法(这个方法名可以和路径名不一样)
- 执行save()方法
- 检测到有@ResponseBody,将save方法的返回值作响应体反应给请求方
Controller加载控制与业务bean加载控制
在实际开发中Spring管理的bean与SpringMVC管理的bean会因为bean扫描的范围产生冲突
SpringMVC相关的bean控制
- SpringMVC管理的bean要在Controller包内
Spring相关的bean控制
Spring加载bena的扫描范围中排除Controller包,示例
@ComponentScan(value="com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
- excludeFilters 是ComPonentScan注解的一个属性,意思是排除过滤器,
- FilterType.ANNOTATION是按注解过滤,为classes.赋值SpringMVC相关bean类的注解,就能过滤掉被@Contoroller注解的bean
Spring记载bean的扫描范围更精准,例如com.itshicha.dao
这里有个细节就是,SpringMVC配置类上的@Configuration要删掉,不然加载Spring配置类时会把SpringMVC里的bean加载进Spring容器里,就与Spring扫描的排除冲突了