@EnableAutoConfiguration是如何导入spring.factories的

@EnableAutoConfiguration

@EnableAutoConfiguration的注解

一、时序图时序图

二、流程

在这里插入图片描述

refresh() ->
invokeBeanFactoryPostProcessors() -> PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
方法中会调用ConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry方法
在这里插入图片描述
在得到有且仅有一个candidate也就是主启动类之后,进入
ConfigurationClassParserparse方法
doProcessConfigurationClass方法中会对@Import进行处理
getImports(sourceClass)即递归迭代所有注解,找到所有@Import
在这里插入图片描述
@EnableAutoConfiguration导入的AutoConfigurationImportSelector是一个DeferredImportSelector

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered{
		...
		...
}

因此会推迟处理。

if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
		Class<?> candidateClass = candidate.loadClass();
		ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
				this.environment, this.resourceLoader, this.registry);
		Predicate<String> selectorFilter = selector.getExclusionFilter();
		if (selectorFilter != null) {
			exclusionFilter = exclusionFilter.or(selectorFilter);
		}
		//将AutoConfigurationImportSelector加入集合,延迟处理
		if (selector instanceof DeferredImportSelector) {
			this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
		}
		else {
			String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
			Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
			processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
		}
}

来到parse方法中,
在这里插入图片描述

public void process() {
		List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
		this.deferredImportSelectors = null;
		try {
			if (deferredImports != null) {
				DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
				deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
				//生成AutoConfigurationGroup.class放入groupings,此处不是重点
				deferredImports.forEach(handler::register);
				//真正处理
				handler.processGroupImports();
			}
		}
		finally {
			this.deferredImportSelectors = new ArrayList<>();
		}
}

最终在handler.processGroupImports()中处理

public void processGroupImports() {
	for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
		Predicate<String> exclusionFilter = grouping.getCandidateFilter();
		//getImports
		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);
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +		configurationClass.getMetadata().getClassName() + "]", ex);
			}
		});
	}
}

getImports() ->
AutoConfigurationGroup.process() ->
AutoConfigurationImportSelector.getAutoConfigurationEntry() ->
getCandidateConfigurations()

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, 				AnnotationAttributes attributes) {
	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
			getBeanClassLoader());
	Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
			+ "are using a custom packaging, make sure that file is correct.");
	return configurations;
}

在这里插入图片描述

总结

可以看到,spring.factories 居然不是由AutoConfigurationImportSelector的selectImports方法导入,而是由getAutoConfigurationEntry方法导入的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值