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

  • 加载SpringMvcConfig
  • 执行@ComponentScan加载对应的bean
  • 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  • 执行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)*/
    1. Spring加载的bean设定范围为精准范围,例如service包,dao包等
    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({"com.itheima.service","com.itheima.dao"})public class SpringConfig {}Servlet容器简化写法我们的Servlet容器中可以定义Spring和SpringMVC的配置文件
    package com.itheima.config;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {// 配置SpringMVC配置文件protected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringMvcConfig.class);return ctx;}// 配置Spring配置文件protected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringConfig.class);return ctx;}// 配置拦截路径protected String[] getServletMappings() {return new String[]{"/"};}}
    我们可以注意到:
    Spring和SpringMVC导入方法中均采用AnnotationConfigWebApplicationContext来创建对象
    两者之间的区别仅仅是class包的不同
    Spring给了我们一种新的继承类用于简化开发:

    经验总结扩展阅读