文章目录
@SpringBootApplication
作用在spring boot主类上,标识程序为spring boot应用,是@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan三个注解的集合
@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) })
public @interface SpringBootApplication {
}
@SpringBootConfiguration
- 标识程序为spring boot应用,方便spring boot拓展,实际就是@Configuration,表示当前类为配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@ComponentScan
- 扫描配置类,默认扫描@ManagedBean和@Component注解配置的类
- 在@SpringBootApplication注解中添加了两个默认过滤器TypeExcludeFilter(通过继承该类实现排除拓展)和AutoConfigurationExcludeFilter(排除其他配置类上存在@EnableAutoConfiguration注解的类)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
// 扫描包的位置com.king.XX
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
// 默认扫描指定类:@ManagedBean和@Component
boolean useDefaultFilters() default true;
// 过滤器,包含或排除指定类
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
}
@EnableAutoConfiguration
自动配置注解,根据路径下的包或类来创建Bean
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// 排除特定的自动配置类,使其永远不会被应用
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
AutoConfigurationImportSelector
- 实现ImportSelector接口,实现外部配置的导入
- 实现DeferredImportSelector接口,在所有配置类解析完成后加载,交给DeferredImportSelectorGroupingHandler注册处理
- 首先将DeferredImportSelector注册到DeferredImportSelectorGrouping中
public void register(DeferredImportSelectorHolder deferredImport) {
// 获得所属组
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
// 创建DeferredImportSelectorGrouping实例,设置beanFactory、类加载、资源加载
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));
// 将当前导入选择器加入组中
grouping.add(deferredImport);
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());
}
- 处理组中的导入选择器
- getExclusionFilter获得过滤器,可通过AutoConfigurationImportFilter类实现自定义过滤器
- 获得需要导入的配置类
- 处理导入的配置类,添加到ConfigurationClasses中等待加载
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
// 获得当前组的过滤器(默认过滤java.lang.annotation和org.springframework.stereotype包下的类 + getExclusionFilter方法排除的类)
Predicate<String> exclusionFilter = grouping.getCandidateFilter();
// 获得需要导入的配置类
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
// 处理配置类
processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
exclusionFilter, false);
}
···异常
});
}
}
2.1 获得导入配置类
public Iterable<Group.Entry> getImports() {
// 获得所有需要导入的配置类
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
// 获得所有配置类并排序(通过@AutoConfigureOrder排序)
return this.group.selectImports();
}
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
···提示
// 从META-INF/spring.factories中获得EnableAutoConfiguration类,默认过滤器过滤OnBeanCondition、OnClassCondition、OnWebApplicationCondition
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
// 将需导入的配置类加入entries中
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
@AutoConfigurationPackage
将注解所在类的包名保存在AutoConfigurationPackages中,存入IOC容器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
// 包路径
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
AutoConfigurationPackages.Registrar
- 实现ImportBeanDefinitionRegistrar接口,在ConfigurationClass加载时,调用registerBeanDefinitions方法将类导入IOC容器中
- 如果未设置basePackages属性则默认为注解所在类下的包