一篇文章带你掌握主流服务层框架——SpringMVC( 二 )

/*我们服务层的实际操作都是放置于Servlet容器中我们配置的SpringMVC和Spring环境都是用于服务层 , 所以我们需要把相关Config加载仅Servlet容器中*/package com.itheima.config;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;// web容器配置类// AbstractDispatcherServletInitializer是SpringMVC为我们设置好的类,继承并实现相关方法即可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;}}我们对上述新的内容进行解析:

  1. @Controller
    • 名称:@Controller
    • 类型:类注解
    • 位置:SpringMVC控制类定义上方
    • 作用:设定SpringMVC的核心控制器Bean
  2. @RequestMapping
    • 名称:@RequestMapping
    • 类型:方法注解
    • 位置:SpringMVC控制器方法定义上方
    • 作用:设置当前控制器方法请求访问路径
    • 相关属性:value(请求访问路径)
  3. @ResponseBody
    • 名称:@ResponseBody
    • 类型:方法注释
    • 位置:SpringMVC控制器方法定义上方
    • 作用:设置当前控制器方法响应内容为当前返回值,无需解析
  4. AbstractDispatcherServletInitializer类
    • AbstractDispatcherServletInitializer是SpringMVC提供的快速初始化Web3.0容器的抽象类
    • AbstractDispatcherServletInitializer提供三个接口方法供用户实现
    • createServletApplicationContext方法用于创建Servlet容器时,加载SpringMVC对应的Bean并放入
    • AnnotationConfigWebApplicationContext的作用范围对应整个Web容器范围,必须使用WebApplicationcontext类型
最后我们总结一下上述操作的出现频率:
  • 一次性工作
    • 创建工程,设置服务器,加载工程
    • 导入坐标
    • 创建Web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
    • SpringMVC核心配置类(设置配置类,扫描controller包 , 加载Controller控制器Bean)
  • 常态工作
    • 定义处理请求的控制类
    • 定义处理请求的操作方法,并设置映射路径(@RequestMapper)与返回Json数据(@ResponseBody)
SpringMVC工作流程在分析SpringMVC工作流程前 , 我们需要知道服务层是由下面的框架组成的:
一篇文章带你掌握主流服务层框架——SpringMVC

文章插图
启动服务器初始化过程:
  1. 服务器启动 , 执行ServletContainersInitConfig类,初始化Web容器
  2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
  3. 加载SpringMvcConfig
  4. 执行@ComponentScan加载对应的bean
  5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC
单次请求过程:
  1. 发送请求localhost/save
  2. Web容器发现所有请求都经过SpirngMVC , 将请求交给SpringMVC处理
  3. 解析请求路径/save
  4. 由/save匹配执行对应的方法save()
  5. 执行save()
  6. 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方
SpringMVC加载控制在学习SpringMVC之后,我们的Bean的范围逐渐变大:
  • SpringMVC相关bean(表现层bean)
  • Spring相关bean(业务层Service,功能DataSource等)
但是我们在使用时,需要区分相关bean的导入路径:
  • SpringMVC加载的bean对应的包均在com.itheima.controller包内
  • Spring加载的bean却包含有多个文件夹
因而我们给出两种方法来解决Spring的扫描问题:
  1. Spring加载的bean设定范围为com.itheima,并排除掉controller包内的bean
package com.itheima.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.stereotype.Controller;@Configuration/*@ComponentScan注解设置扫描范围@ComponentScan中包含有value,excludeFilters属性value:用于控制扫描范围excludeFilters:用于控制排除范围 , 需要采用@ComponentScan.Filter过滤器type:设置排除规则 , 当前使用按照bean定义时的注解类型进行排除classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean*/@ComponentScan(value="https://www.huyubaike.com/biancheng/com.itheima",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class))public class SpringConfig {}/*这里做一个小补充内容:@ComponentScan中除了excludeFilters,还包括有includeFiltersincludeFilters:加载指定的bean , 需要指定类型(type)和具体项(classes)*/

推荐阅读