简记
@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
- @SpringBootConfiguration
一般一个工程中只有1 个这样的注解。而且一般使用@SpringBootApplication,而不是直接用@SpringBootConfiguration。该注解类似于@Configuration,用于定义 java bean。
Spring Boot favors Java-based configuration. As a result, the @SpringBootConfiguration annotation is the primary source for configuration in applications. Generally, the class that defines the main() method is a good candidate for this annotation.
@SpringBootConfiguration is an alternative to the @Configuration annotation. The main difference is that @SpringBootConfiguration allows configuration to be automatically located. This can be especially useful for unit or integration tests.
The recommendation is to only have one @SpringBootConfiguration or @SpringBootApplication for your application. Most applications will simply use @SpringBootApplication.
- @EnableAutoConfiguration
主要用于该应用依赖的第三方jar 包中的 bean 被自动加载到 spring 容器中。并且第三方的 jar 包一般会在 resources 下定义META-INF/spring.factories文件。
// 忽略部分代码
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// 忽略部分代码
}
重点逻辑在AutoConfigurationImportSelector中。
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 忽略部分代码
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 忽略部分代码
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 忽略部分代码
return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// 从META-INF/spring.factories加载
List<String> configurations = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()));
ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add);
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;
}
- @ComponentScan
用于扫描该应用类(main 方法所在的类)所在 package 下的所有 bean。一般的组织结构如下:Main类在根 package 的下面。在大型应用下,一般会将 service 层的代码放在独立的 module 下面,这个时候,独立 module 的 package 需要跟该应用类的 package 一样。