SpringMVC:SpringMVC的bean加载机制

问题分析

入门案例的内容已经做完了,在入门案例中我们创建过一个SpringMvcConfig的配置类,再回想前面咱们学习Spring的时候也创建过一个配置类SpringConfig。这两个配置类都需要加载资源,那么它们分别都需要加载哪些内容?

我们先来看下目前我们的项目目录结构:

  • config目录存入的是配置类,写过的配置类有:

    • ServletContainersInitConfig
    • SpringConfig
    • SpringMvcConfig
    • JdbcConfig
    • MybatisConfig
  • controller目录存放的是SpringMVC的controller类,如:UserController

  • service目录存放的是service接口和实现类

  • dao目录存放的是dao/Mapper接口

controller、service和dao这些类都需要被容器管理成bean对象,那么到底是该让SpringMVC加载还是让Spring加载呢?

  • SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
  • Spring 控制的bean
    • 业务bean(Service)
    • 功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)

分析清楚谁该管哪些bean以后,接下来要解决的问题是如何让Spring和SpringMVC分开加载各自的内容:

  • SpringMVC的配置类
    在SpringMVC的配置类SpringMvcConfig中使用注解@ComponentScan,我们只需要将其扫描范围设置到controller即可,如
  • Spring的配置类
    在Spring的配置类SpringConfig中使用注解@ComponentScan,当时扫描的范围**@ComponentScan("itheima")**,这里"itheima"其实是已经包含了controller,如:

概括的描述下咱们现在的问题就是因为功能不同,如何避免Spring错误加载到SpringMVC的bean?

解决方案

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

具体该如何排除:

方式一:

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

java 复制代码
@Configuration
@ComponentScan({"com.itheima.service","comitheima.dao"})
public class SpringConfig {
}

说明:

上述只是通过例子说明可以精确指定让Spring扫描对应的包结构,真正在做开发的时候,因为Dao最终是交给MapperScannerConfigurer对象来进行扫描处理的,我们只需要将其扫描到service包即可。
方式二:

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

java 复制代码
@Configuration
@ComponentScan(value="com.itheima",
    excludeFilters=@ComponentScan.Filter(
    	type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
}
  • excludeFilters属性:设置扫描加载bean时,排除的过滤规则

  • type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除

    • ANNOTATION:按照注解排除
    • ASSIGNABLE_TYPE:按照指定的类型过滤
    • ASPECTJ:按照Aspectj表达式排除,基本上不会用
    • REGEX:按照正则表达式排除
    • CUSTOM:按照自定义规则排除

    大家只需要知道第一种ANNOTATION即可

  • classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean

方式三:

不区分Spring与SpringMVC的环境,加载到同一个环境中[了解即可]

tomcat服务器启动加载Spring的配置类

有了Spring的配置类,要想在tomcat服务器启动将其加载,我们需要修改ServletContainersInitConfig,将之前的createRootApplicationContext返回null改成返回Spring的配置:

java 复制代码
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对应的配置类:

java 复制代码
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[]{"/"};
    }
}

知识点1:@ComponentScan

名称 @ComponentScan
类型 类注解
位置 类定义上方
作用 设置spring配置类扫描路径,用于加载使用注解格式定义的bean
相关属性 excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)和具体项(classes) includeFilters:加载指定的bean,需要指定类别(type)和具体项(classes)

[声明]:内容主要来源黑马程序员网上资源学习

相关推荐
张较瘦_6 分钟前
环境搭建 | [入门级]VSCode(Cursor|Trae|Qoder)搭建Java(Springboot3)企业开发环境全流程
java·ide·vscode
007php00710 分钟前
百度面试题解析:synchronized、volatile、JMM内存模型、JVM运行时区域及堆和方法区(三)
java·开发语言·jvm·缓存·面试·golang·php
YSRM14 分钟前
Leetcode+Java+图论II
java·leetcode·图论
十铭忘16 分钟前
基于SAM2的眼动数据跟踪2
java·服务器·前端
okjohn27 分钟前
浅谈需求分析与管理
java·架构·系统架构·软件工程·产品经理·需求分析·规格说明书
用户03321266636741 分钟前
Java添加、设置和删除PDF图层:
java
荣光波比1 小时前
K8S(十)—— Kubernetes核心组件详解:Pod控制器与配置资源管理
java·容器·kubernetes
m0_651593911 小时前
企业级订单系统架构设计:领域驱动 vs 数据驱动实践指南
java·系统架构·领域驱动ddd
WangMing_X1 小时前
C#上位机软件:2.5 体验CLR实现多语言混合编程
java·开发语言·c#
青云交1 小时前
Java 大视界 -- Java 大数据在智慧交通停车场智能管理与车位预测中的应用实践
java·数据采集·数据清洗·智慧交通·停车场智能管理·智能收费系统·车位预测