1,* SpringMVC的创建步骤:
- **SpringMVC的项目包结构:**
- 
* 导入SpringMVC坐标和Servlet坐标:
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 导入springmvc的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
A,创建Spring核心配置类:
//表明这个是配置类
@Configuration
public class SpringConfig {
}
B,创建SpringMVC核心配置类:
@Configuration
//扫描控制器包,设置SpringMVC要记载的bean
@ComponentScan ("top.jztice5.controller")
//开启webmvc的功能
@EnableWebMvc
public class SpringMvcConfig {
}
* 如果不用@EnableWebMvc注解开启WebMVC功能的话,那就要再创建一个配置类继承WebMvcConfigurationSupport以开启WebMVC的功能:
这里定义为:SpringMVCSupport(设置放行前端页面的静态资源并会自动开启WebMVC的功能(部分))
/**
* 添加静态资源管理器组件
* 把静态资源放行
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("启动静态资源放行...");
//添加所有静态资源文件夹,访问路径表示所有子孙目录都被映射,后面参数必须以*号结尾;
//放行静态资源;
// 当访问/pages/xxx时候,走/pages目录下的内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
/**
* 添加拦截器组件
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// 配置注解拦截器和拦截控制器方法请求地址
registry.addInterceptor(new BookInterceptor()).addPathPatterns("/books/**");
}
C,创建Servlet配置类:
初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截路径;
继承的类: AbstractAnnotationConfigDispatcherServletInitializer
package top.jztice5.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
/**
* @author Jztice5
* @date 2022年03月27日 10:43
*/
//Servlet属性配置类
public class ServletConfigInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载Spring配置文件
@Override
protected Class <?>[] getRootConfigClasses () {
return new Class[]{SpringConfig.class};
}
//加载SpringMVC的配置文件
@Override
protected Class <?>[] getServletConfigClasses () {
return new Class[]{SpringMvcConfig.class};
}
//指定SpringMVC拦截路径
@Override
protected String[] getServletMappings () {
//“/” :表示拦截所有资源; 注意:这里的拦截资源是指:由SpringMVC将资源拦截下来进行数据处理;
return new String[]{"/"};
}
@Override
protected Filter[] getServletFilters () { //设置编码过滤器,重写方法
//创建用于进行编码设定的对象;
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
//设置编码类型为utf8
characterEncodingFilter.setEncoding("utf8");
//返回编码对象到容器中,方便取用;
return new Filter[]{characterEncodingFilter};
}
}
注意:getServletMappings () 方法中的拦截路径是指:将什么资源拦截到SpringMVC框架中进行处理;(web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理) 如:“ / ” 就是将所有的资源由SpringMVC框架拦截下来,经过框架,根据子路径找到对应的控制器访问路径进行处理;(详见下方代码)
D,创建控制器类,测试框架是否创建成功:
控制器类 = 以前使用的Servlet;
- 设定请求方法的返回值为字符串,并返回自定义的JSON数据;
//表明为控制器,将对象放到容器中,到时候就由框架自动调用控制器对象;
@Controller
public class UserController {
//控制器请求的访问地址
@RequestMapping ("/save")
//设置当前控制器方法响应的内容为当前返回值;
@ResponseBody
public String save () {
System.out.println("1");
return "{'info':'springmvc'}";
}
}
- 如成功,则显示如下图:
2,* SpringMVC在上述案例中使用的注解分析:
注解,与注解类型: | 作用: |
---|---|
@Controller (类注解) | 定义SpringMVC的核心控制器bean |
@RequestMapping(方法注解) | 设置当前控制器方法请求的访问路径 |
@ResponseBody (方法注解) | 设置当前控制器方法相应内容为当前返回值,无需解析; |
3,SpringMVC 简介:AbstractDispatcherServletInitializer
- 在 Servlet 3.0 环境下,Servlet 容器会在 classpath下搜索实现了 javax.servlet.ServletContainerInitializer接口的任何类,找到之后用它来初始化 Servlet 容器。
- Spring 实现了以上接口,实现类叫做 SpringServletContainerInitializer, 它会依次搜寻实现了 WebApplicationInitializer接口的任何类,并委派这个类实现配置。
- 而AbstractDispatcherServletInitializer的父类则实现了WebApplicationInitializer接口。
- AbstractDispatcherServletInitializer提供三个接口方法供用户实现
- 服务器启动,执行ServletConfig类,初始化web容器;
- 执行createServletApplicationContext方法,创建了WebApplicationContext对象;
- 加载SpringMvcConfig;
- 执行@ComponentScan加载对应的bean;
- 加载UserController,每个@RequestMapping的名称对应一个具体的方法;
执行getServletMappings方法,定义所有的请求都通过SpringMVC;
5,单次请求的过程:
- 发送请求localhost/save;
- web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理;
- 解析请求路径/save;
- 由/save匹配执行对应的方法save();
- 执行save();
- 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方;
6,* Spring和SpringMVC框架整合的本质:
- Spring和SpringMVC框架的整合本质上是两个Spring容器的整合,因为我们知道SpringMVC框架本质也是一个Spring容器,所以这里所谓的整合就是在web容器中配置两个Spring容器,并让他们各司其职。
- Spring管理service,dao,事务等相关的组件的注入
- SpringMVC管理控制器相关的组件controller。
- 父子容器:
- Spring容器对应的是父容器,SpringMVC容器对应的是子容器。从容器里面getBean的时候,先从本容器取,如果取不到再从父容器取。
- IoC容器体系中可以有多个子容器,但是父容器只有一个。不同的子容器之间不能共享bean,但是子容器都可以获得父容器中的bean信息。
- 父容器和子容器被初始化后会以属性的形式被存储在ServletContext上下文域中以供调用。因此处理器对象(子容器中)可以获取Service对象(父容器)并且注入,反过来业务对象不能获取处理器对象。
简单来说,SpringMVC就是处理与Web的层进行请求与响应的一种框架技术;而Spring就是三层架构中的Service层,作为中间人进行数据的处理;这两样技术结合就是了SSM中的SS;
7,* Controller加载控制与业务bean加载控制:
Spring 与 SpringMVC 整合的项目结构示例:(实际使用请按照项目要求进行设置)
A,SpringMVC与Spring对应的bean:
- SpringMVC相关的bean(表现层bean);Web
- Spring控制的Bean:
- 业务层(Service)bean;
- 功能bean(DataSource,Mybatis等);
B,SpringMVC相关bean加载控制:
- SpringMVC加载的bean对应的包均在com.itheima.controller包内;
C,Spring相关的bean加载控制:
- **方式 一:**Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean;
- **方式 二:**Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等;
- **方式 三:**不区分Spring与SpringMVC的环境,加载到同一个环境中;
简单来说,SpringMVC就是处理与Web的层进行请求与响应的一种框架技术;而Spring就是三层架构中的Service层,作为中间人进行数据的处理;这两样技术结合就是了SSM中的SS;