SpringBoot的自动化配置原理

@SpringBootApplication所在包是org.springframework.boot:spring-boot-autoconfigure:1.5.22.RELEASE

@SpringBootApplication有三个重要注解,其中有个@EnableAutoConfiguration注解,在@EnableAutoConfiguration注解上有一行

@Import({AutoConfigurationImportSelector.class})

AutoConfigurationImportSelector实现了ImportSelector接口.重写了selectImports方法

SpringBoot程序启动时,在refresh()方法中

this.invokeBeanFactoryPostProcessors(beanFactory);

org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors

org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions,这里就是处理Config类的逻辑了.

org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate在这里找到被@Configration标记的类.

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());

然后处理

org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)

org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process

org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports

org.springframework.context.annotation.ConfigurationClassParser#processImports在这里处理导入的 类

String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());

最终调用了selectImports方法

if (selector instanceof DeferredImportSelector) {
    this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector)selector);
} else {
    String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
    Collection<ConfigurationClassParser.SourceClass> importSourceClasses = this.asSourceClasses(importClassNames, exclusionFilter);
    this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}

AutoConfigurationImportSelector实现了DeferredImportSelector接口,所以调用了handle方法.

再来看看 selectImports方法

this.getAutoConfigurationEntry(annotationMetadata);

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations 在这里加载所有的配置类

org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories这里加载了

META-INF/spring.factories下的所有字符串
try {
            // META-INF/spring.factories
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					String[] factoryImplementationNames =
							StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
					for (String factoryImplementationName : factoryImplementationNames) {
						result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
								.add(factoryImplementationName.trim());
					}
				}
			}

			// Replace all lists with unmodifiable lists containing unique elements
			result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
					.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
			cache.put(classLoader, result);
		}

最后返回了一个数组,包含了所有需要自动导入的类的全限定名,就是META-INF/spring.factories的值

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

然后是bean初始化的那一套了

this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();

 

参考:

spring加载流程之ConfigurationClassPostProcessor

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值