@SpringBootApplication
在Spring Boot应用中,使用@SpringBootApplication来标注一个主程序类。
@SpringBootApplication注解中包含了以下的注解
@EnableAutoConfiguration
其中@EnableAutoConfiguration注解用于开启自动配置功能,该注解中包含了以下注解
@AutoConfigurationPakage
其中的@AutoConfigurationPackage注解,包含了一个@Import(AutoConfigurationPackages.Registrar.class)注解,
@Import注解是Spring的底层注解,用于给容器中导入一个组件,导入的组件由后面的类中指定
在导入的AutoConfigurationPackages.Registrar类中,包含一个registrarBeanDefinitions方法
1 public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { 2 register(registry, new PackageImport(metadata).getPackageName()); 3 }
在该方法中,通过new PackageImport(metadata).getPackageName()获得注解元信息中的包名,这个包名就是主配置类所在的包名。
因此,@AutoConfigurationPackage的作用就是将主配置类(@SpringBootApplication标注的类)所在的包及下面所有子包里的所有组件扫描到Spring容器中。这也是其他类必须为主配置类子包或者同级的原因。
@Import(AutoConfigurationImportSelector.class)
这个Import注解依然用于导入组件,其中AutoConfigurationImportSelector为导入哪些组件的选择器;这个类中的selectImports()方法将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。
1 @Override 2 public String[] selectImports(AnnotationMetadata annotationMetadata) { 3 if (!isEnabled(annotationMetadata)) { 4 return NO_IMPORTS; 5 } 6 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader 7 .loadMetadata(this.beanClassLoader); 8 AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, 9 annotationMetadata); 10 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); 11 }
第8行的getAutoConfigurationEntry()方法就是获取需要添加的组件,这些组件包含了很多自动配置类(XXXAutoConfiguration),这些自动配置类的作用就是给容器中导入所需要的所有组件,并配置好这些组件。方法代码如下
1 protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, 2 AnnotationMetadata annotationMetadata) { 3 if (!isEnabled(annotationMetadata)) { 4 return EMPTY_ENTRY; 5 } 6 AnnotationAttributes attributes = getAttributes(annotationMetadata); 7 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 8 configurations = removeDuplicates(configurations); 9 Set<String> exclusions = getExclusions(annotationMetadata, attributes); 10 checkExcludedClasses(configurations, exclusions); 11 configurations.removeAll(exclusions); 12 configurations = filter(configurations, autoConfigurationMetadata); 13 fireAutoConfigurationImportEvents(configurations, exclusions); 14 return new AutoConfigurationEntry(configurations, exclusions); 15 }
有了自动配置类,就不需要我们再手动配置和注入功能组件等工作。
自动配置类扫描原理:
在getAutoConfigurationEntry()方法中,第7行的getCandidateConfigurations() 方法中有这一行代码:
1 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), 2 getBeanClassLoader());
这行代码的作用就是从类路径下的MATA-INF/spring.factories中获取EnableAutoConfiguration指定的值,而EnableAutoConfiguration就为自动配置的内容。
Spring Boot在启动的时候从类路径下的MATA-INF/spring.factories中获取EnableAutoConfiguration指定的值。将这些值作为自动配置类导入到容器中,自动配置类就生效,进行自动配置工作。以前需要我们自己配置的东西,自动配置类都会帮我们完成