什么是SpringBoot自动装配?(含图文详解)

什么是 SpringBoot 自动装配

SpringBoot 的自动配置是 SpringBoot 框架的核心特性之一。可以自动配置和加载 SpringBoot 所需的各种组件和功能,从而大大的减少开发人员手动配置的工作。

在传统的 Spring 应用程序中,我们需要手动配置各种组件,如数据源、Web 容器、事务管理器等。这些配置需要编写大量的 XML 配置文件或 Java 配置类,增加了开发的工作量和复杂性。而 SpringBoot 的自动装配通过约定优于配置的理念,根据项目的依赖和配置信息,自动进行配置,使得开发人员无需进行大量的手动配置。

用 Redis 举例来理解自动装配:
我们在项目中使用 Redis 时,往往有以下几步:

  1. 引入 Redis 依赖–starter
  2. 配置 Redis 服务器
  3. 可以直接使用 RedisTemplate Bean 对象了

我们用 Maven 引入了一个 starter ,其余的什么都没有做,但是 SpringBoot 自动完成了 Redis 的配置。

说白了就是:当 Spring 容器启动时,一些配置类、bean 对象就自动存入 IOC 容器中,不需要我们手动声明,从而简化了开发,省去了繁琐的配置操作。在 SpringBoot 应用里面只需要在启动类上加上 @SpringBootApplication 注解就可以实现自动装配。

Springboot 加载配置类的两大方式

  1. 使用 @ComponentScan
    ● 对指定的 package 进行扫描,找到其中符合条件的类,默认是搜索被注解 @Component 修饰的类。
    ● 通过属性 basePackages 或 basePackagesClassses,来指定要扫描的 package。
    ● 如果未指定 package,则默认扫描当前 @ComponentScan 所修饰的类所在的 package。

  2. 使用 @Import
    @Import 提供了一种显示地从其他地方加载配置类的方式,其他地方通常指第三方的 jar 包。
    ● 导入普通类(这里的普通类是相对于随后两个接口而言的)
    ● 导入选择器 ImportSelector 的实现类。ImportSelector 接口有一个 selectorImport 方法,它的返回值是一个字符串数组,数组中的每个元素分别代表一个将被导入的配置类的全限定类名。利用该特性,我们可以给 IoC 容器动态的导入多个配置类。
    ● 导入注册器 ImportBeanDefinitionRegister 的实现类。通过这个接口我么可以将多个 BeanDefinition 注册到 IoC 容器中。

应当使用哪一个方式来加实现自动配置呢?
3. 使用 @ComponentScan 加载自动配置类很不方便,开发人员需要记住每一个第三方 jar 包的 package 名称,然后把他们写入应用程序中。
4. 使用 @Import 导入普通类比使用 @ComponentScan 还要麻烦,甚至需要第三方 jar 包中的具体类名。
5. 使用 @Import 导入 ImportBeanDefinitionRegister 也不合适,BeanDefinition 注册器的设计目标是对 @Bean 方法的补充,他是 BeanDefinition 层面的。

因此选用了@Import 导入选择器 ImportSelector 来实现自动配置!!!!

SpringBoot 自动装配流程

@SpringBootApplication 是一个复合注解,该注解主要是由三个注解组成:

  1. @SpringBootConfiguration:用来声明配置类
  2. @EnableAutoConfiguration:Springboot 实现自动化配置的核心注解
  3. @ComponentScan:组件扫描,只扫描 Springboot 项目包内的 Bean 并注册到 Spring 容器中

真正实现自动装配的是 @EnableAutoConfiguration注解。
在这里插入图片描述
@EnableAutoConfiguration 注解最终导入了 AutoConfigurationImportSelector.class 类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage  
@Import(AutoConfigurationImportSelector.class) 
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
	Class<?>[] exclude() default {};
    String[] excludeName() default {};
} 

如何实现 AutoConfigurationImportSelector ?

通过 SpringFactories 机制:
○ Java SPI 机制的延伸和扩展
○ Spring 框架的基础机制,在 Spring 以及 SpringBoot 源码中到处可见
○ 可以基于它来实现 SpringBoot 的自动配置功能
○ 它的核心逻辑是从 classpath 中读取到所有 Jar 包中的配置文件 META-IF/spring.factories 然后根据指定的 key 从配置文件中解析出对应的 value 值

AutoConfigurationImportSelector 通过 selectImports() 方法告诉 SpringBoot 都需要导入哪些组件。selectImports() 方法使用内部工具类 SpringFactoriesLoader 查找 classpath 上所用 jar 包中的 MATE-INF/spring.factories 进行加载, 实现将配置类信息交给 SpringFactory 加载器进行一系列的容器创建过程。

Java SPI 补充介绍: Java SPI 主要是应用于厂商自定义组件或插件中。在 java.util.ServiceLoader 的文档里有比较详细的介绍。简单的总结下 java SPI 机制的思想:我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块、xml 解析模块、jdbc 模块等方案。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制

自动装配流程如下:

  1. 我们的启动类上有@SpringBootApplication

  2. 子注解 @SpringBootConfiguration,间接被 @Configuration 修饰,即启动类是一个源配置类

  3. 子注解 @ComponentScan,对源配置类所在的 Package 进行组件扫描

  4. 子注解 @EnableAutoConfiguration,最终导入一个 AutoConfigurationImportSelector 组件来实现自动配置

  5. 在这个 AutoConfigurationImportSelector 类内部会基于 selectImports() 方法使用内部工具类 SpringFactoriesLoader 的 loadFactoryNames() 方法查找 classpath 上所用 jar 包中的 MATE-INF/spring.factories 进行加载。
    在这里插入图片描述

  6. 根据这些自动配置类上的条件注解 @Conditional 进行过滤,过滤出满足条件的自动配置类,然后通过 Spring 提供的 ImportSelector 接口来加载这些自动配置类,从而得到这些自动配置类的 BeanDefinition,最后根据 BeanDefinition 实例化对象。

总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值