SpringBoot - 自动装配
SpringBoot 最核心的功能就是自动装配,
Starter 作为 SpringBoot 的核心功能之一,基于自动配置代码提供了自动配置模块及依赖的能力,让软件集成变得简单、易用。使用 SpringBoot 时,我们只需引人对应的 Starter,SpringBoot 启动时便会自动加载相关依赖,集成相关功能,这便是 SpringBoot 的自动装配功能。
简单概括其自动配置的原理:由@SpringBootAppliction组合注解中的@EnableAutoConfiguration注解开启自动配置,加载 spring.factories 文件中注册的各种 AutoConfiguration 配置类,当其 @Conditional 条件注解生效时,实例化该配置类中定义的 Bean,并注入 Spring 上下文。
SpringBoot 自动装配过程涉及以下主要内容:@EnableAutoConfiguration: 扫描类路径下的META-INF/spring.factories文件,并加载其中中注册的 AutoConfiguration 配置类,开启自动装配;
spring.factories:配置文件,位于 jar 包的 META-INF 目录下,按照指定格式注册了 AutoConfiguration 配置类;AutoConfiguration 类:自动配置类,SpringBoot 的大量以 xxxAutoConfiguration 命名的自动配置类,定义了三方组件集成 Spring 所需初始化的 Bean 和条件;@Conditional 条件注解及其行生注解:使用在 AutoConfiguration 类上,设置了配置类的实例化条件;Starter:三方组件的依赖及配置,包括 SpringBoot 预置组件和自定义组件,往往会包含 spring.factories 文件、AutoConfiguration 类和其他配置类。其功能间的作用关系如下图:
1. @EnableAutoConfiguration
2. @AutoConfigurationImportSelector
@EnableAutoConfiguration的自动配置功能是通过@Import注解导入的ImportSelector来完成的。 @Import(AutoConfigurationlmportSelector.class)是@EnableAutoConfiguration注解的组成部分,也是自动配置功能的核心实现者。下面讲解@Import的基本使用方法和ImportSelector的实现类AutoConfigurationlmportSelector。
2. @Import
@Import注解,提供了导入配置类的功能。SpringBoot 的源代码中,有大量的EnableXXX类都使用了该注解,了解@Import有助于我们理解 SpringBoot 的自动装配,@Import有以下三个用途:
通过@Import引入@Configuration注解的类;
导入实现了ImportSelector或ImportBeanDefinitionRegistrar的类;
通过@lmport导入普通的POJO。
3. AutoConfigurationlmportSelector 实现类
@Import的许多功能都需要借助接口ImportSelector来实现,ImportSelector决定可引人哪些 @Configuration的注解类,ImportSelector接口源码如下:
java 代码解读复制代码public interface ImportSelector {
String[] selectImports(AnnotationMetadata importingClassMetadata);
}
ImportSelector接口只提供了一个参数为AnnotationMetadata的方法,返回的结果为一个字符串数组。其中参数AnnotationMetadata内包含了被@Import注解的类的注解信息。在selectimports方法内可根据具体实现决定返回哪些配置类的全限定名,将结果以字符串数组的形式返回。如果实现了接口ImportSelector的类的同时又实现了以下4个Aware接口,那么 Spring 保证在调用ImportSelector之前会先调用Aware接口的方法。这4个接口为:EnvironmentAware、BeanFactoryAware、 BeanClassLoaderAware和ResourceLoaderAware。
在AutoConfigurationlmportSelector的源代码中就实现了这4个接口:
四、@Conditional 注解
@Conditional 注解允许你根据特定的条件来动态配置 Spring Bean。换句话说,只有在特定条件满足的情况下,Spring 才会实例化和注入标注了 @Conditional 的 Bean。
@Conditional 注解本身并不包含具体的条件逻辑,而是依赖于实现了 Condition 接口的类来定义条件逻辑。使用时需要将实现了 Condition 接口的类作为参数传递给 @Conditional 注解。
1. Condition 接口
1 package org.springframework.context.annotation; 2 3 import org.springframework.core.type.AnnotatedTypeMetadata; 4 5 @FunctionalInterface 6 public interface Condition { 7 boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); 8 }
Spring 提供了一些常用的 @Conditional 注解,用于处理常见的条件逻辑:
@ConditionalOnProperty: 根据配置属性来判断是否注入 Bean。
@ConditionalOnClass: 当类路径中存在特定的类时注入 Bean。
@ConditionalOnMissingBean: 当容器中不存在特定的 Bean 时注入。
@ConditionalOnBean: 当容器中存在特定的 Bean 时注入。
@ConditionalOnWebApplication: 只有在 Web 应用环境中才注入 Bean。
@ConditionalOnExpression: 根据 SpEL 表达式的结果来判断是否注入 Bean。
参考链接:https://juejin.cn/post/7137095650160115743