一、SpringMVC 概述

SpringMVC  是一种基于  Java  实现  MVC  模型的轻量级  Web 框架


优点:

(1)使用简单、开发便捷 ( 相比于 Servlet)

(2)灵活性强

二、SpringMVC 入门案例

①:使用 SpringMVC 技术需要先导入 SpringMVC 坐标与 Servlet 坐标

<dependencies>
    <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>
  </dependencies>
②:创建 SpringMVC 控制器类(等同于 Servlet 功能)
//定义表现层控制器bean
@Controller
public class UserController {

    //设置映射路径为/save,即外部访问路径
    @RequestMapping("/save")
    //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }

    //设置映射路径为/delete,即外部访问路径
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }
}
③:初始化 SpringMVC 环境(同 Spring 环境),设定 SpringMVC 加载对应的 bean
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
④:初始化 Servlet 容器,加载 SpringMVC 环境,并设置 SpringMVC 技术处理的请求
//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    protected WebApplicationContext createServletApplicationContext() {
        //初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        //加载指定配置类
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring配置类
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}




SpringMVC基础习题_mvc


三、工作流程解析

将  SpringMVC  的使用过程总共分两个阶段来分析,分别是 启动服务器初始化过程和 单次请求过程

SpringMVC基础习题_MVC_02



1. 启动服务器初始化过程

(1) 服务器启动,执行  ServletContainersInitConfig  类,初始化  web  容器功能类似于以前的web.xml

(2) 执行  createServletApplicationContext  方法,创建了  WebApplicationContext 对象该方法加载  SpringMVC  的配置类  SpringMvcConfig  来初始化  SpringMVC  的容器

(3) 加载 SpringMvcConfig 配置类


(4) 执行  @ComponentScan  加载对应的 bean。扫描指定包及其子包下所有类上的注解,如 Controller  类上的  @Controller  注解

(5) 加载  UserController ,每个  @RequestMapping 的名称对应一个具体的方法。此时就建立了 /save 和 save 方法的对应关系


(6) 执行  getServletMappings  方法,设定  SpringMVC 拦截请求的路径规则。【/】 代表所拦截请求的路径规则,只有被拦截后才能交给  SpringMVC  来处理请求



2. 单次请求过程

(1) 发送请求  http://localhost/save

(2)web  容器发现该请求满足  SpringMVC  拦截规则,将请求交给  SpringMVC  处理

(3) 解析请求路径  /save

(4) 由  /save  匹配执行对应的方法  save( )

上面的第五步已经将请求路径和方法建立了对应关系,通过  /save  就能找到对应的  save  方法

(5) 执行 save()

(6) 检测到有 @ResponseBody 直接将 save() 方法的返回值作为响应体返回给请求方

四、bean 加载控制

因为功能不同,如何避免 Spring 错误加载到 SpringMVC bean?

加载 Spring 控制的 bean 的时候排除掉 SpringMVC 控制的 bean

方式一: Spring 加载的 bean 设定扫描范围为精准范围,例如 service 包、 dao 包等

@Configuration@ComponentScan({"com.itheima.service","com.itheima.dao"}) public class SpringConfig { }

方式二: Spring 加载的 bean 设定扫描范围为 com.itheima, 排除掉 controller 包中的 bean

@Configuration//@ComponentScan({"com.itheima.service","com.itheima.dao"})
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
}

方式三: 不区分 Spring 与 SpringMVC的环境,加载到同一个环境中(了解即可)

有了  Spring  的配置类,要想在  tomcat 服务器启动将其加载,我们需要修改 ServletContainersInitConfig

public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

}

对于上述的配置方式, Spring  还提供了一种更简单的配置方式,可以不用再去创建

AnnotationConfigWebApplicationContext  对象,不用手动  register  对应的配置类

//web配置类简化开发,仅设置配置类类名即可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[]{"/"};
    }
}

SpringMVC基础习题_MVC_03