当前位置: 首页 > news >正文

【Spring】SpringBoot 自动配置,@ComponentScan、@Import、ImportSelector接口

文章目录

  • 什么是 SpringBoot 自动配置
  • Spring 加载 Bean
    • 问题描述
    • 原因分析
    • 解决方案
      • @ComponentScan
      • @Import
        • 1 . 导入类
        • 2 . 导入 ImportSelector 接口实现类
        • 问题

什么是 SpringBoot 自动配置

SpringBoot 的自动配置就是当 Spring 容器启动之后,一些配置类,bean 对象就自动存入到了 IoC 容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作

SpringBoot 自动配置,就是指 SpringBoot 是如何将依赖 jar 包中的配置以及 Bean 加载到 Spring IoC 容器中的

我们学习主要分以下两个方面:

  1. Spring 是如何把对象加载到 SpringIoC 容器中的
  2. SpringBoot 是如何实现的

Spring 加载 Bean

问题描述

需求:使用 Spring 管理第三方的 jar 包的配置

  • 引入第三方的包,其实就是在该项目下,引入第三方的代码,我们采用在该项目下创建不同的目录来模拟第三方的代码引入

数据准备

  1. 创建项目 spring-autoconfig,当前项目目录为:com.example.demo
  2. 模拟第三方代码文件在 com.bite.autoconfig 目录下image.png|251

第三方文件代码:

public class BiteConfig {  public void study() {  System.out.println("start study...");  }  
}
  1. 获取 BiteConfig 这个 Bean

写测试代码

@SpringBootTest  
class ApplicationTests {  @Autowired  private ApplicationContext applicationContext;  @Test  void contextLoads() {  BiteConfig biteConfig = applicationContext.getBean(BiteConfig.class, "biteConfig");  System.out.println(biteConfig);  }  
}
  1. 运行程序
    image.png
  • 观察日志:No qualifying bean of type 'com.bite.autoconfig.BiteConfig' available
  • 没有 com.bite.autoconfig.BiteConfig 这个类型的 Bean

原因分析

Spring 通过五大注解和 @Bean 注解可以帮助我们把 Bean 加载到 SpringIoC 容器中,以上有个前提就是这些注解类需要和 SpringBoot 启动类在同一个目录下(@SpringBootApplication 标注的类就是 SpringBoot 的启动类)

  • 启动类所在目录为:com.example.deml,而 BiteConfig 这个类在 com.bite.autoconfig 下,所以 SpringBoot 没有扫描到

解决方案

我们需要指定路径或者引入的文件,告诉 spring,让 Spring 进行扫描到

常见的解决方案有两种:

  1. @ComponentScan 组件扫描
  2. Import 导入(使用 @Import 导入的类会被 Spring 加载到 IoC 容器中)

我们通过代码来看如何解决

@ComponentScan

通过 @ComponentScan 注解,指定 Spring 扫描路径

@ComponentScan("com.bite.autoconfig")  
@SpringBootApplication  
public class Application {  public static void main(String[] args) {  SpringApplication.run(Application.class, args);  }  }
  • 可以指定扫描多个包 @ComponentScan({"com.bite.autoconfig","com.example.demo"})

运行程序:image.png|403

可以看到,这次 biteConfigBean 获取到了

  • Spring 是否使用了这种方式呢?
  • 非常明显,没有(因为我们引入第三方框架时,没有加扫描路径,如 mybatis
  • 如果 SpringBoot 采用这种方式,当我们引入大量的第三方依赖,比如 MyBatisjackson 等时,就需要在启动类上配置不同依赖需要扫描的包
  • 这种方式会非常繁琐

@Import

@Import 导入主要有以下几种形式

  1. 导入类
  2. 导入 ImportSelector 接口实现类

1 . 导入类
@Import(BiteConfig.class)  
@SpringBootApplication  
public class Application {  public static void main(String[] args) {  SpringApplication.run(Application.class, args);  }  }
  • 运行程序image.png
  • 可以看到,这种方式也可以告诉 Spring 加载 biteConfig

问题:如果又多了一些配置项呢?

@Component  
public class BiteConfig2 {  public void study2() {  System.out.println("start study2...");  }  
}

我们可以采用导入多个类

@Import({BiteConfig.class, BiteConfig2.class})  
@SpringBootApplication  
public class Application {  public static void main(String[] args) {  SpringApplication.run(Application.class, args);  }  }

很明显,这种方式也很繁琐,所以,SpringBoot 依然没有采用

2 . 导入 ImportSelector 接口实现类

ImportSelector 接口实现类

public class MyImportSelector implements ImportSelector {  @Override  public String[] selectImports(AnnotationMetadata importingClassMetadata) {  // 需要导入的全限定类名  return new String[]{"com.bite.autoconfig.BiteConfig", "com.bite.autoconfig.BiteConfig2"};  }  
}

启动类:

@Import(MyImportSelector.class)  
@SpringBootApplication  
public class Application {  public static void main(String[] args) {  SpringApplication.run(Application.class, args);  }  }

运行程序:image.png|472

  • 可以看到,我们采用这种方式也可以导入第三方依赖提供的 Bean

问题

问题
但是他们都有一个明显的问题,就是使用者需要知道第三方依赖中有哪些 Bean 对象或配置类。如果漏掉了其中一些 Bean,就可能导致我们的项目出现大事故

依赖中有哪些 Bean,使用时需要配置哪些 Bean,第三方依赖最清楚,那能否由典发那个依赖来做这件事呢?

  • 比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以 @EnableXxxx 开头,注解中封装的就是 @Import 注解

  1. 第三方依赖提供注解
import org.springframework.context.annotation.Import;  import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  @Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@Import(MyImportSelector.class)  
public @interface EnableBiteConfig {  
}

注解中封装 @Import 注解,导入 MyImportSelector.class

  1. 在启动类上使用第三方提供的注解
@EnableBiteConfig  
@SpringBootApplication  
public class Application {  public static void main(String[] args) {  SpringApplication.run(Application.class, args);  }  }

运行程序:image.png

  • 可以看到,这种方式也可以导入第三方依赖提供的 Bean
  • 并且这种方式更优雅一点,SpringBoot 采用的也是这种方式
http://www.lryc.cn/news/610061.html

相关文章:

  • 【QT】安装与配置
  • 计量学基础 - (二)计量单位制
  • NX982NX984美光固态闪存NX992NY102
  • 高速信号设计之 PCIe6.0 篇
  • Linux之Shell脚本快速入门
  • 【2025最新】Spring Boot + Spring AI 玩转智能应用开发
  • 微服务的编程测评系统10-竞赛删除发布-用户管理-登录注册
  • 雷达系统工程学习:自制极化合成孔径雷达无人机
  • Flask全栈入门:打造区块链艺术品交易所
  • Oracle 定时任务相关
  • Tomcat虚拟主机配置详解和多实例部署
  • k8s的毫核
  • 太阳光模拟器塑料瓶暴晒试验
  • Vue2实现docx,xlsx,pptx预览
  • P1002 [NOIP 2002 普及组] 过河卒
  • ubuntu22.04系统实践 linux基础入门命令(三) 用户管理命令
  • SpringMVC实战指南:从环境搭建到功能实现全解析
  • 先知模型或者说从容的模型
  • RTOS如何保证实时性
  • React 入门:环境搭建、JSX、组件、事件与状态管理
  • 云原生攻防6(Kubernetes扩展知识)
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第五天(jQuery函数库)
  • 官宣朱珠成为集团品牌代言人,转转推动二手消费新风尚
  • Linux-Day02.Linux指令
  • 如何设计和实施高效的向量化数据检索解决方案
  • Apache IoTDB(3):时序数据库 IoTDB Docker部署实战
  • 大模型部署、nvidia-smi、token数
  • Linux服务器管理MySQL数据库的常见命
  • 09 Linux基础(8.4)
  • git 项目拉取 SSH密钥配置