目录
[1、 @SpringBootApplication 注解](#1、 @SpringBootApplication 注解)
编辑(1)@SpringbootConfiguration
一、引言
springboot 的自动装配(Auto-Configuration)是一种特性,它可以基于类路径上的条件以及属性文件中的设置自动配置 Spring 应用程序,简化开发人员需要编写的配置代码。
详情可以查阅:springboot参考指南
二、自动装配原理
自动装配实际上就是把第三方组件的Bean装载到IOC容器里,不需要开发人员再去写Bean相关的一个配置
三、核心注解解析
1、 @SpringBootApplication注解
通常只需要在SpringBoot应用启动类上加上 @SpringBootApplication 注解,就可以去实现自动装配。
@SpringBootApplication注解是一个复合注解,其主要包含三个重要的注解,@SpringBootConfiguration,@EnableAutoConfiguration和@ComponentScan
真正去实现自动装配的注解其实是 @EnableAutoConfiguration 注解。
(1)@SpringbootConfiguration
@SpringBootConfiguration 本质上就是
@Configuration
,用于指定一个类是配置类。
(2)@ComponentScan
注解默认会扫描启动类所在的包下所有的类 ,为后续装配工作提供资源支持(也可以自定义不扫描某些包下的类)。
(3)@EnableAutoConfiguration
@EnableAutoConfiguration是自动配置的核心,它引导自动配置机制。
通过 @Import(AutoConfigurationImportSelector.calss)来引入AutoConfigurationImportSelector
AutoConfigurationImportSelector的作用是根据项目的依赖和配置情况,动态地选择并加载适合的自动配置类。
AutoConfigurationImportSelector的继承关系如下:
AutoConfigurationImportSelector
类通过重写实现了 ImportSelector
接口中的selectImports
方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IOC容器 中。
java
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
ImportSelector
接口用于实现动态地选择需要被导入到容器中的配置类的逻辑
java
public interface ImportSelector {
/**
* @param importingClassMetadata 用于描述使用了 @Import 注解的配置类的注解元数据。
* @return 数组中的每个元素都是一个全限定类名,表示需要被导入到容器中的配置类。
*/
String[] selectImports(AnnotationMetadata var1);
/**
* 提供一个可选的排除过滤器,决定哪些配置类应该被排除在外。
* 默认返回 null,表示没有排除过滤器。
*/
@Nullable
default Predicate<String> getExclusionFilter() {
return null; // 默认没有排除过滤器
}
}
getAutoConfigurationEntry方法通过一系列步骤,包括检查自动配置是否启用、获取候选配置、去除重复项、获取排除配置、检查排除的类是否有效、移除排除项、过滤配置,最终生成一个包含自动配置类和排除配置类的AutoConfigurationEntry对象。
getAutoConfigurationEntry方法是Spring Boot自动配置功能的核心,它确保了只有符合条件的自动配置类被加载到Spring应用上下文中。
java
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 如果自动配置未启用,则返回空的自动配置条目
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
// 获取注解的属性
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 获取候选的自动配置类
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
// 移除重复的自动配置类
configurations = this.removeDuplicates(configurations);
// 获取需要排除的自动配置类
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
// 检查排除的类是否在候选配置类中
this.checkExcludedClasses(configurations, exclusions);
// 从候选配置类中移除排除的类
configurations.removeAll(exclusions);
// 使用配置类过滤器过滤自动配置类
configurations = this.getConfigurationClassFilter().filter(configurations);
// 触发自动配置导入事件
this.fireAutoConfigurationImportEvents(configurations, exclusions);
// 返回自动配置条目
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
接下来,我们debug看一下具体各个步骤内容:
1、判断自动装配开关是否打开,默认是spring.boot.enableautoconfiguration=true,可以在application.properties或者application.yml中设置开启或关闭。
2、获取EnableAutoConfiguration注解中的exclude 和excluedeName
3、获取需要自动装配的所有配置类,读取META-INF/spring.factories
4、在spring boot中,spring.factories文件中列出了许多自动配置类,但是这并不意味着每次应用启动时所有这些配置都会被加载。Spring Boot采用了一种称为条件配置的机制,使得只有在特定条件满足时,相关的自动配置类才会被激活和加载。
我们继续进行debug
可以发现,configurations的size值变小了,意味着并不是所有的配置都被加载了进去。
2、条件装配(Conditional系列注解)
Spring Boot在进行自动装配时并不是会盲目的把所有类全部装配进去,而是会有选择的进行,通过@Conditional系列注解来实现选择,常见条件包括:
@ConditionalOnClass:当类路径中存在某个类时才生效。
@ConditionalOnMissingBean:当 Spring 上下文中不存在某个 Bean 时才生效。
@ConditionalOnProperty:当某个配置属性满足特定条件时才生效。
@ConditionalOnBean:当 Spring 上下文中存在某个 Bean 时才生效。
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置里面的所有内容才生效;