Spring Boot自动配置的原理在于@SpringBootApplication注解下的@EnableAutoConfiguration,因此我们从这个配置类开始分析,主要分析过程都写在代码中了。
@EnableAutoConfiguration
- 这个注解是Spring Boot自动配置的关键,其中Import了另一个DefferedImportSelector的实现类AutoConfigurationImportSelector
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// 。。。。。。。
}
- 简单介绍以下DefferedImportSelector的原理
- Spring的后置处理器在解析配置类时会解析到配置类上的@Import注解,当Import的注解为DefferedImportSelector的实现类时,会将其添加到ConfigurationClassParser的一个属性deferredImportSelectorHandler,而这个属性中又有一个列表保存了DeferredImportSelectorHolder的实例,这个实例是在解析的时候根据配置类以及他引入的DefferedImportSelector构建的
- 在某一配置类引入的类全部被递归解析完成后,才会执行到this.deferredImportSelectorHandler.process()方法,执行之前添加的DefferedImportSelector
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 执行之前添加的DefferedImportSelector
this.deferredImportSelectorHandler.process();
}
- process方法中会创建一个DeferredImportSelectorGroupingHandler,然后根据是否返回了非空的DeferredImportSelector.Group类,如果返回的是null或者没有重写getImportGroup方法,则使用默认的DefaultDeferredImportSelectorGroup,然后把所有相同Group的DeferredImportSelector添加到一起。最后调用DeferredImportSelectorGroupingHandler的processGroupImports方法。
public void process() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}
// DeferredImportSelectorGroupingHandler类的方法
public void register(DeferredImportSelectorHolder deferredImport) {
Class<? extends Group> group = deferredImport.getImportSelector()
.getImportGroup();
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());
}
- processGroupImports会遍历之前封装好的DeferredImportSelectorGrouping,然后调用它的getImports方法
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(
entry.getMetadata());
try {
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}
- getImports方法中会对相同Group的DeferredImportSelector执行process和selectImports方法,这里就会因为前面的AutoConfigurationImportSelector中实现的getImportGroup方法而跳转到Spring Boot自动配置的关键方法中,即AutoConfigurationGroup的process和selectImports方法;这里再讲一下,如果DeferredImportSelector的getImportGroup方法返回null,那么就会执行到DefaultDeferredImportSelectorGroup的process和selectImports方法,这里就会直接调用DeferredImportSelector的selectImports方法
public Iterable<Group.Entry> getImports() {
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
return this.group.selectImports();
}
查找自动配置类
下面我们进入本文的重点,自动配置。
- process方法
@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
// 调用了AutoConfigurationImportSelector的getAutoConfigurationEntry方法
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
- getAutoConfigurationEntry
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
// 判断配置文件的自动配置功能是否打开,即环境中是否设置了spring.boot.enableautoconfiguration,默认返回true,取反为false
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
// 获取到@EnableAutoConfiguration注解的属性
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 获取到META/spring.factories文件中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的全限定类名
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 剔除重复的
configurations = removeDuplicates(configurations);
// 查找到@EnableAutoConfiguration中exclude,excludeName中的全限定类名,或者配置文件中spring.autoconfigure.exclude添加的全限定类名
// 以便剔除不需要自动配置的类
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
// 检查上一步剔除的类,如果该排除的类可以被加载并且之前从spring.factories中没有指定过该类名,那么就是一个无效的排除,然后打印一下
checkExcludedClasses(configurations, exclusions);
// 删除有效的剔除类名
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
- filter方法获取掉不需要的类,SpringBoot默认实现有以下3个,后面我们依次来看
org.springframework.boot.autoconfigure.condition.OnBeanCondition
org.springframework.boot.autoconfigure.condition.OnClassCondition
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
long startTime = System.nanoTime();
String[] candidates = StringUtils.toStringArray(configurations);
boolean[] skip = new boolean[candidates.length];
boolean skipped = false;
for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
invokeAwareMethods(filter);
// 使用各个Filter对候选的自动配置类进行筛选
boolean[] match = filter.match(candidates, autoConfigurationMetadata);
for (int i = 0; i < match.length; i++) {
// 如果不符合过滤器的条件,那么就标识该配置类为需要跳过,将候选的置为null,标志是否有任意一个需要跳过
if (!match[i]) {
skip[i] = true;
candidates[i] = null;
skipped = true;
}
}
}
// 如果全部都没有要跳过,直接返回所有的
if (!skipped) {
return configurations;
}
// 根据前面filter判断的结果,决定是否添加到结果中返回
List<String> result = new ArrayList<>(candidates.length);
for (int i = 0; i < candidates.length; i++) {
if (!skip[i]) {
result.add(candidates[i]);
}
}
if (logger.isTraceEnabled()) {
int numberFiltered = configurations.size() - result.size();
logger.trace("Filtered " + numberFiltered + " auto configuration class in "
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
}
return new ArrayList<>(result);
}
上面提供到3个过滤器都是继承自FilteringSpringBootCondition,而match方法由FilteringSpringBootCondition,getOutcomes由实现类重写
public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionEvaluationReport report = ConditionEvaluationReport.find(this.beanFactory);
ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses, autoConfigurationMetadata);
boolean[] match = new boolean[outcomes.length];
for (int i = 0; i < outcomes.length; i++) {
match[i] = (outcomes[i] == null || outcomes[i].isMatch());
if (!match[i] && outcomes[i] != null) {
logOutcome(autoConfigurationClasses[i], outcomes[i]);
if (report != null) {
report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);
}
}
}
return match;
}
OnClassCondition类分析
protected final ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
AutoConfigurationMetadata autoConfigurationMetadata) {
// Split the work and perform half in a background thread. Using a single
// additional thread seems to offer the best performance. More threads make
// things worse
// 二分法处理
int split = autoConfigurationClasses.length / 2;
// 创建一个线程用于处理前一半的数据,创建了一个ThreadedOutcomesResolver,构造器中传入StandardOutcomesResolver,
// 然后在构造器中启动一个线程执行构造器中传入StandardOutcomesResolver.resolveOutcomes方法,并将返回值赋值给ThreadedOutcomesResolver的
// outcomes属性
OutcomesResolver firstHalfResolver = createOutcomesResolver(autoConfigurationClasses, 0, split,
autoConfigurationMetadata);
OutcomesResolver secondHalfResolver = new StandardOutcomesResolver(autoConfigurationClasses, split,
autoConfigurationClasses.length, autoConfigurationMetadata, getBeanClassLoader());
// 步骤
// 1. 获取META-INF/spring-autoconfigure-metadata.properties文件中的配置,key为:自动配置类名 + "." + "ConditionalOnClass"
// 2. 如果上述属性获取到了,判断该属性值对应的类是否可以加载到,如果加载得到返回null,加载得到,返回一个属性为false的ConditionOutcome
ConditionOutcome[] secondHalf = secondHalfResolver.resolveOutcomes();
// 调用ThreadedOutcomesResolver的resolveOutcomes方法,调用当前方法中之前创建的thread.join方法,等待线程把StandardOutcomesResolver.resolveOutcomes
// 执行完成,然后把赋值好的outcomes返回
ConditionOutcome[] firstHalf = firstHalfResolver.resolveOutcomes();
// 组合返回
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
System.arraycopy(firstHalf, 0, outcomes, 0, firstHalf.length);
System.arraycopy(secondHalf, 0, outcomes, split, secondHalf.length);
return outcomes;
}
回到上面的代码中
public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionEvaluationReport report = ConditionEvaluationReport.find(this.beanFactory);
ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses, autoConfigurationMetadata);
boolean[] match = new boolean[outcomes.length];
for (int i = 0; i < outcomes.length; i++) {
// outcome为null或者outcome的match为true,那么就说明需要自动配置
match[i] = (outcomes[i] == null || outcomes[i].isMatch());
if (!match[i] && outcomes[i] != null) {
// 打印不能使用自动配置的类
logOutcome(autoConfigurationClasses[i], outcomes[i]);
if (report != null) {
report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);
}
}
}
return match;
}
OnWebApplicationCondition,直接看getOutcomes方法,同样获取META-INF/spring-autoconfigure-metadata.properties文件中的配置,key为:自动配置类名 + “.” + “ConditionalOnWebApplication”,根据该值决定是否自动注入
protected ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
for (int i = 0; i < outcomes.length; i++) {
String autoConfigurationClass = autoConfigurationClasses[i];
if (autoConfigurationClass != null) {
outcomes[i] = getOutcome(
autoConfigurationMetadata.get(autoConfigurationClass, "ConditionalOnWebApplication"));
}
}
return outcomes;
}
有哪些值?
1. 未配置;
2. SERVLET:项目引入_org.springframework.web.context.support.GenericWebApplicationContext,返回null
3. REACTIVE:项目引入_org.springframework.web.reactive.HandlerResult,返回null
4. 其他:引入了上述两种之一即返回null
private ConditionOutcome getOutcome(String type) {
if (type == null) {
return null;
}
ConditionMessage.Builder message = ConditionMessage.forCondition(ConditionalOnWebApplication.class);
if (ConditionalOnWebApplication.Type.SERVLET.name().equals(type)) {
if (!ClassNameFilter.isPresent(SERVLET_WEB_APPLICATION_CLASS, getBeanClassLoader())) {
return ConditionOutcome.noMatch(message.didNotFind("servlet web application classes").atAll());
}
}
if (ConditionalOnWebApplication.Type.REACTIVE.name().equals(type)) {
if (!ClassNameFilter.isPresent(REACTIVE_WEB_APPLICATION_CLASS, getBeanClassLoader())) {
return ConditionOutcome.noMatch(message.didNotFind("reactive web application classes").atAll());
}
}
if (!ClassNameFilter.isPresent(SERVLET_WEB_APPLICATION_CLASS, getBeanClassLoader())
&& !ClassUtils.isPresent(REACTIVE_WEB_APPLICATION_CLASS, getBeanClassLoader())) {
return ConditionOutcome.noMatch(message.didNotFind("reactive or servlet web application classes").atAll());
}
return null;
}
OnBeanCondition,和前两种一样,获取META-INF/spring-autoconfigure-metadata.properties文件中的配置,key为:自动配置类名 + “.” + “ConditionalOnBean”,如果前一个没有过滤掉,在判断ConditionalOnSingleCandidate的类型
protected final ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
for (int i = 0; i < outcomes.length; i++) {
String autoConfigurationClass = autoConfigurationClasses[i];
if (autoConfigurationClass != null) {
Set<String> onBeanTypes = autoConfigurationMetadata.getSet(autoConfigurationClass, "ConditionalOnBean");
outcomes[i] = getOutcome(onBeanTypes, ConditionalOnBean.class);
if (outcomes[i] == null) {
Set<String> onSingleCandidateTypes = autoConfigurationMetadata.getSet(autoConfigurationClass,
"ConditionalOnSingleCandidate");
outcomes[i] = getOutcome(onSingleCandidateTypes, ConditionalOnSingleCandidate.class);
}
}
}
return outcomes;
}
过滤掉条件不满足的类
/**
requiredBeanTypes: 必须要有的bean的类型全限定名
该方法用于判断任意一个需要加载的类不存在,即返回false的ConditionOutcome
*/
private ConditionOutcome getOutcome(Set<String> requiredBeanTypes, Class<? extends Annotation> annotation) {
List<String> missing = filter(requiredBeanTypes, ClassNameFilter.MISSING, getBeanClassLoader());
if (!missing.isEmpty()) {
ConditionMessage message = ConditionMessage.forCondition(annotation)
.didNotFind("required type", "required types").items(Style.QUOTE, missing);
return ConditionOutcome.noMatch(message);
}
return null;
}
- 过滤完成后继续调用getAutoConfigurationEntry方法中的fireAutoConfigurationImportEvents方法,该方法查找spring.factories中的org.springframework.boot.autoconfigure.AutoConfigurationImportListener, 向该监听器发布一个AutoConfigurationImportEvent事件
private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners();
if (!listeners.isEmpty()) {
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
for (AutoConfigurationImportListener listener : listeners) {
invokeAwareMethods(listener);
listener.onAutoConfigurationImportEvent(event);
}
}
}
onAutoConfigurationImportEvent,向ConditionEvaluationReport中记录自动配置类和排除过的类
public void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event) {
if (this.beanFactory != null) {
ConditionEvaluationReport report = ConditionEvaluationReport.get(this.beanFactory);
report.recordEvaluationCandidates(event.getCandidateConfigurations());
report.recordExclusions(event.getExclusions());
}
}
- 调用selectImports方法
public Iterable<Entry> selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
// 获取到所有的排除
Set<String> allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
// 所有的自动配置类
Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
// 再剔除一次
processedConfigurations.removeAll(allExclusions);
// 排序,并且封装成List<Entry>返回
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
- 下面我们来看如何排序,创建一个AutoConfigurationSorter的类用于排序
private List<String> sortAutoConfigurations(Set<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) {
return new AutoConfigurationSorter(getMetadataReaderFactory(), autoConfigurationMetadata)
.getInPriorityOrder(configurations);
}
- 然后调用getInPriorityOrder方法,在这个方法中新建一个AutoConfigurationClasses的类,在这个类的构造方法中调用addToClasses,将配置类和他们依赖的@AutoConfigureBefore和@AutoConfigureAfter的类放到属性classes中
private void addToClasses(MetadataReaderFactory metadataReaderFactory,
AutoConfigurationMetadata autoConfigurationMetadata, Collection<String> classNames, boolean required) {
// 遍历之前扫描出来spring.factories的所有自动配置类
for (String className : classNames) {
// 判断是否已经添加过
if (!this.classes.containsKey(className)) {
// 封装成AutoConfigurationClass对象
AutoConfigurationClass autoConfigurationClass = new AutoConfigurationClass(className,
metadataReaderFactory, autoConfigurationMetadata);
// 判断是否可用,判断条件如下
// 1. 如果是spring-autoconfigure-metadata.properties中申明过的,直接返回true
// 2. 如果条件1不满足,判断当前类的class文件或者内部类class文件是否能被加载到,能则返回true
// 3. 上述条件不满足返回false
boolean available = autoConfigurationClass.isAvailable();
// 递归的根方法中一定会添加,即从spring.factories中找到并过滤后的类一定会被添加
// 被AutoConfigureBefore和AutoConfireAfter引入的类如果不满足上面available的条件,则不添加
if (required || available) {
this.classes.put(className, autoConfigurationClass);
}
if (available) {
// 首先autoConfigurationClass.getBefore()方法找到指定的类,查找原则如下:
// 1.如果当前类名是在spring-autoconfigure-metadata.properties中配置了,
// 那么就找这个配置文件下key为 类名 + ".AutoConfigureBefore"对应类
// 2.如果spring-autoconfigure-metadata.properties下未配置类名的key,就查找该类的注解上@AutoConfigureBefore对应的类
// 然后递归查找
addToClasses(metadataReaderFactory, autoConfigurationMetadata,
autoConfigurationClass.getBefore(), false);
// after的同样的逻辑
addToClasses(metadataReaderFactory, autoConfigurationMetadata,
autoConfigurationClass.getAfter(), false);
}
}
}
}
- 回到getInPriorityOrder中,
public List<String> getInPriorityOrder(Collection<String> classNames) {
AutoConfigurationClasses classes = new AutoConfigurationClasses(this.metadataReaderFactory,
this.autoConfigurationMetadata, classNames);
List<String> orderedClassNames = new ArrayList<>(classNames);
// Initially sort alphabetically
// 先按名称顺序排序
Collections.sort(orderedClassNames);
// 按前面解析出来的AutoConfigurationClass的getOrder排序,getOrder的逻辑和判断before和after类似
// 即查看spring-autoconfigure-metadata.properties或者@AutoConfigureOrder注解的Value值,越小越排前
orderedClassNames.sort((o1, o2) -> {
int i1 = classes.get(o1).getOrder();
int i2 = classes.get(o2).getOrder();
return Integer.compare(i1, i2);
});
// Then respect @AutoConfigureBefore @AutoConfigureAfter
// 然后respect @AutoConfigureBefore @AutoConfigureAfter
// 根据这个配置,再次排序
orderedClassNames = sortByAnnotation(classes, orderedClassNames);
return orderedClassNames;
}
- sortByAnnotation
private List<String> sortByAnnotation(AutoConfigurationClasses classes, List<String> classNames) {
// 待排序的
List<String> toSort = new ArrayList<>(classNames);
toSort.addAll(classes.getAllNames());
// 排好序的
Set<String> sorted = new LinkedHashSet<>();
// 正在执行排序的
Set<String> processing = new LinkedHashSet<>();
// 每遍历一个,remove一个
while (!toSort.isEmpty()) {
doSortByAfterAnnotation(classes, toSort, sorted, processing, null);
}
// 求交集,最终只返回spring.factories中EnableAutoConfiguration的类
// 为什么求交集,因为这里排序只是为了保证我们需要的顺序,而不是决定我们后续需要执行哪些配置类的解析,如果需要在它之前执行的配置类没有,
// 并不影响我当前类的配置解析,而如果要判断是否解析,应该由@Conditional来决定
sorted.retainAll(classNames);
return new ArrayList<>(sorted);
}
private void doSortByAfterAnnotation(AutoConfigurationClasses classes, List<String> toSort, Set<String> sorted,
Set<String> processing, String current) {
if (current == null) {
current = toSort.remove(0);
}
processing.add(current);
// 判断当前需要排序的类是否有需要在某个类之后配置
// 如果有
for (String after : classes.getClassesRequestedAfter(current)) {
// 断言正在执行排序的类是不是包含了需要先配置的类,如果包含了,那么说明这两个类都需要对方在前,那么会导致死循环,因此抛出异常
Assert.state(!processing.contains(after),
"AutoConfigure cycle detected between " + current + " and " + after);
// 如果已经排好序的类中有需要先排序的这个类,说明需要提前把这个类先往前排,因此递归调用,递归调用时current传入需要先排序的这个类
// 因此在最开始的判断current == null时不会为true,因此不会从待排序的队列中剔除,然后继续执行这个for逻辑,如果有继续递归,如果没有
// 将当前的类名,添加到sorted的列表中,后续在遍历的过程中,依然会在toSort的列表中遍历到该类名,但由于sorted是一个LinkedHashSet
// 不允许重复,因此即使重复遍历,也不会产生重复的数据
// 如果上述条件不满足说明,需要先排序的已经在前面排好了序,那么就不用管这个类了
if (!sorted.contains(after) && toSort.contains(after)) {
doSortByAfterAnnotation(classes, toSort, sorted, processing, after);
}
}
processing.remove(current);
// 最终,所有需要先排序的都提前先进入sorted,因此完成了排序
sorted.add(current);
}
- 执行完上面的操作后,我们拿到了所有被引入的自动配置类,因此可以回到上面DeferredImportSelectorGroupingHandler的processGroupImports方法了,这个方法,把获取到自动配置类作为配置类进行解析,后续流程参考我另外一篇文章
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(
entry.getMetadata());
try {
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}
- 以上就是Spring Boot自动配置的原理流程啦