Spring Boot的应用启动都是在创建项目后自动生成主配置类的Application代码:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
进入到注解配置@SpringBootApplication
中可以看到:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
其中@EnableAutoConfiguration
就是开启自动配置类的注释;
自动配置原理
Spring Boot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
,在进入该注解之后:
@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 {};
}
其中的注解@Import({AutoConfigurationImportSelector.class})
使用选择器给容器中导入一些组件。其中有一个方法protected List<String> getCandidateConfigurations()
获取候选的配置,下面来简单看一下该方法:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
SpringFactoriesLoader.loadFactoryNames()方法用来扫描jar包的类路径下的META-INF/spring.factories
,SpringFactoriesLoader
类中的loadSpringFactories(@Nullable ClassLoader classLoader)
方法负责把扫描的文件封装称properties对象,而this.getSpringFactoriesLoaderFactoryClass()
方法负责从properties中获取到EnableAutoConfiguration.class
类对应的值把他们添加到容器中;
即就是将类路径下的 META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值添加到了容器中