关上主程序的代码,如下:
@SpringBootApplicationpublic class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); }}
能够看到主程序很简略,只有一个注解 @SpringBootApplication,这就是springboot启动的外围
点击 @SpringBootApplication 进去,能够发现它是一个组合注解,包含两个外围注解:
@SpringBootConfiguration@EnableAutoConfigurationpublic @interface SpringBootApplication {……}
点击@SpringBootConfiguration 进去,能够看到它只有一个注解@Configuration:
@Configurationpublic @interface SpringBootConfiguration {……}
@Configuration 代表着这是一个 Spring 配置类,能够认为 @SpringBootConfiguration = @Configuration
再点击另一个注解 @EnableAutoConfiguration进去看,能够看到蕴含两个注解
@AutoConfigurationPackage@Import({AutoConfigurationImportSelector.class})public @interface EnableAutoConfiguration {……}
点击 @AutoConfigurationPackage 进去,能够看到:
@Import({Registrar.class})public @interface AutoConfigurationPackage {……}
再点 Registrar 进去,看到这个办法:
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));}
默认状况下,就是将主配置类(@SpringBootApplication)所在的包以及子包里的组件扫描到容器中。
回到EnableAutoConfiguration,点击 AutoConfigurationImportSelector 进去,能够看到有个 getCandidateConfigurations()办法,能够通过外面的loadFactoryNames()获取所有配置:
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
再点开 SpringFactoriesLoader.loadFactoryNames()办法,能够看到:
而在 SpringFactoriesLoader.loadFactoryNames() 办法参数中点开 getSpringFactoriesLoaderFactoryClass(),返回的是EnableAutoConfiguration.class:
protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class;}
也就是导入资源类,在 META-INF/spring.factories 中找,把key为 EnableAutoConfiguration 的资源加载进来:
然而,spring.factories中这么多配置,并不会在启动的时候全副加装,关上RedisAutoConfiguration ,能够看到:
所以是通过 @ConditionalOnClass 注解判断是否加装该配置
主动配置加载过程如下: