# @EnableAutoConfiguration 注解
@EnableAutoConfiguratioon 注解内部使用 @Import (AutoConfigurationImportSelector.class) 来加载配置类。
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化 Bean
并不是所有的 Bean 都会被初始化,在配置类中使用 Condition 来加载满足条件的 Bean
点击进入 @SpringBootApplication 注解内部
里面有 EnableAutoConfiguration 点击进入查看
@Target(ElementType.TYPE) | |
@Retention(RetentionPolicy.RUNTIME) | |
@Documented | |
@Inherited | |
@AutoConfigurationPackage | |
// 导入了自动配置的 Selector | |
@Import(AutoConfigurationImportSelector.class) | |
public @interface EnableAutoConfiguration { | |
/** | |
* Environment property that can be used to override when auto-configuration is | |
* enabled. | |
*/ | |
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; | |
/** | |
* Exclude specific auto-configuration classes such that they will never be applied. | |
* @return the classes to exclude | |
*/ | |
Class<?>[] exclude() default {}; | |
/** | |
* Exclude specific auto-configuration class names such that they will never be | |
* applied. | |
* @return the class names to exclude | |
* @since 1.3.0 | |
*/ | |
String[] excludeName() default {}; | |
} |
在 AutoConfigurationImportSelector 中重写了 selectImports
@Override | |
// String [] 数组返回定义了很多需要被加载的类 | |
public String[] selectImports(AnnotationMetadata annotationMetadata) { | |
if (!isEnabled(annotationMetadata)) { | |
return NO_IMPORTS; | |
} // 通过 getAutoConfigurationEntry 加载后返回 AutoConfigurationEntry 对象 | |
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); | |
// 将 autoConfigurationEntry 转换为字符串数组 | |
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); | |
} |
查看核心的源代码:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { | |
// 通过 SpringFactoriesLoader 加载并返回 List 集合,这个 List 集合中就是所有需要加载的类 | |
List<String> configurations = new ArrayList<>( | |
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader())); | |
ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add); | |
// 如果上面 List 集合是空的则下面断言抛出错误信息 | |
Assert.notEmpty(configurations, | |
"No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you " | |
+ "are using a custom packaging, make sure that file is correct."); | |
return configurations; | |
} |
如果没有定义 META-INF/spring.factories 文件或者这个文件有问题就会报 configurations 集合加载不到,加载不断就断言失败,失败报出异常,下面看下 spring.factories 文件中定义了哪些需要被自定加载的类
找到 spring-boot-autoconfigure 的依赖包
SpringBoot 启动的时候并不是都会加载这些 Bean,而是判断满足 ConditionalOnClass 注解的条件后才会加载到 IOC 容器中
一般 SpringBoot 官方提供的依赖功能名写在最后面,而第三方提供的功能名写在最前面