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

SpringBoot自动配置

SpringBoot 自动配置的原理是什么?

Spring在启动的时候会自动扫描外部jar包中的META-INF\spring.factories,将文件中的配置类型信息加载到Spring容器,并且执行类中定义的操作。对于外部的jar包来说,只要遵循SpringBoot的标准来,就能将自己的功能配置到SpringBoot中。

SpringBoot 3.0版本开始,自动配置包的路径就将META-INF\spring.factories改成了META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports

SpringBoot 是如何实现自动配置的?

SpringBoot自动配置主要是通过@EnableAutoConfiguratio注解实现的,这个注解包含了@Import(AutoConfigurationImportSelector.class)注解,作用是在启动的时候会自动扫描外部jarclassPath下的所有META-INF\spring.factories(以SpringBoot 2.0为例),根据文件中的指定配置类加载相应的Bean自动配置。

@SpringBootApplication

我们来看看@SpringBootApplication注解的源代码注解

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {// CODE...
}
  • @SpringBootConfiguration:允许上下文额外注入的bean或者导入其他配置类
  • @EnableAutoConfiguration:启动自动配置的机制
  • @ComponentScan:扫描被@Component/@Service/@Controller注解的 bean,注解会默认扫描包下的所有 bean,可以自定义哪些不被扫描,例如TypeExcludeFilter, AutoConfigurationExcludeFilter

img

现在,我们重点关注@EnableAutoConfiguration注解

@EnableAutoConfiguration

要了解该注解的工作机制,我们首先要从源码开始

源码:

...
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// CODE...
}
  • @AutoConfigurationPackage:负责注册主配置所在包以及子包到Spring容器下
  • @Import(AutoConfigurationImportSelector.class):导入自动配置选择器,负责加载和过滤所有自动配置类

AutoConfigurationImportSelector -- 自动配置导入选择器

1)AutoConfigurationImportSelector的继承体制如下:

img

2)入口函数--selectImports()

功能:获取所有符合条件的类的全限定类名,并将这些类需要的加载到IOC容器中

img

3)核心实现--加载自动配置类

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}// 1. 获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata);// 2. 加载候选配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 3. 去重configurations = removeDuplicates(configurations);// 4. 获取排除的配置Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 5. 检查排除的类是否有效checkExcludedClasses(configurations, exclusions);// 6. 移除排除的配置configurations.removeAll(exclusions);// 7. 过滤配置(条件注解处理)configurations = getConfigurationClassFilter().filter(configurations);// 8. 触发事件fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}

关键点说明:

获取所有自动装配的配置类,读取META-INF\spring.factories

// 2. 加载候选配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;
}

留下需要的配置类:

经过getCandidateConfigurations读取META-INF\spring.factories获取到所有自动装配的配置类之后,由于加载太多的配置类会影响Spring容器的性能,因此需要对这些配置类进行排除过滤。

// 4. 获取排除的配置
Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 5. 检查排除的类是否有效
checkExcludedClasses(configurations, exclusions);// 6. 移除排除的配置
configurations.removeAll(exclusions);// 7. 过滤配置(条件注解处理)
configurations = getConfigurationClassFilter().filter(configurations);

实操一遍:

1)判断自动配置是否打开

img

2)获取@EnableAutoConfiguration注解中的excludeexcludeName

...
public @interface EnableAutoConfiguration {// 排除特定的自动配置类,确保永远不会被应用Class<?>[] exclude() default {};// 排除特定的自动配置类名,确保永远不会被应用String[] excludeName() default {};}

效果如下

img

3)获取所有自动装配的配置类,读取META-INF\spring.factories

img

4)去重removeDuplicates(configurations)

通过哈希集合LinkedHashSet<>()去掉重复的配置类

5)获取排除的配置类

比如我们在配置文件中写上:

spring:autoconfigure:exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration是要被排出的

img

说明已经排除成功

6)检查是否排除生效 -- checkExcludedClasses(configurations, exclusions)

7)移除要排除的配置类 -- configurations.removeAll(exclusions)

8)过滤出需要的配置类 -- 按需加载

img

9)触发自动导入事件

fireAutoConfigurationImportEvents(configurations, exclusions)

总结

SpringBoot通过@EnableAutoConfiguration注解自动装配,使用SpringFactoriesLoader加载META-INF/spring.factories中的自动装配的配置类。

end...

http://www.hskmm.com/?act=detail&tid=37729

相关文章:

  • AI元人文构想与余溪诗学空间:一场从诗意本源向智能未来的远征
  • 状压DP
  • 搞定三大PLC通讯:倍福与西门子、欧姆龙与西门子数据互通实战
  • 实验p66
  • 牛客2025秋季算法编程训练联赛2-(基础组提升组)
  • 局域网共享一键通_v2.0.9.9
  • newDay15
  • 每日反思(2025_10_23)
  • 树链剖分/轻重链剖分
  • 如何降低信息化系统的构建成本? ——信息化系统省钱全攻略:从规划到运维的实用技巧
  • C#编程时winform程序登陆记住密码和自动登录功能,关于App.config的问题及解决方案
  • 2025.10.23总结
  • Day2超链接标签
  • Ai元人文构想:你喜欢黑箱与偏见
  • 企业微信 使用api批量处理群消息
  • first game (1)
  • 10月23日日记
  • Gin笔记一之项目建立与运行
  • 软件工程学习日志2025.10.23
  • 10月23号
  • 【题解】P14254 分割(divide)
  • 数论分块 - R
  • 第九届强网杯线上赛PWN_flag-market
  • ISFB银行木马家族演化史:从Gozi到LDR4的技术剖析
  • 10.23日学习笔记
  • 埃氏筛及扩展质因数筛——埃拉托斯特尼筛法变种
  • exgcd板子
  • 2025.10.23
  • 编程练习
  • Codeforces Round 976 (Div. 2) A. Find Minimum Operations