springboot2.7.2版本下对自动配置原理的简单了解

日常使用springboot时spring会按照默认的约定自动注入一些常用的bean。这些bean的beanDefinition信息在refresh()方法的invokeBeanFactoryPostProcessors(beanFactory)这一步被注入。在对beanFactory进行后置处理时,会依次调BeanFactoryPostProcessor,其中ConfigurationClassPostProcessor用来处理配置类,处理过程中通过org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry()方法获取自动配置的类信息

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	
	//获取候选的自动配置类
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	
	configurations = removeDuplicates(configurations);
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	checkExcludedClasses(configurations, exclusions);
	configurations.removeAll(exclusions);
	configurations = getConfigurationClassFilter().filter(configurations);
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);
}

getAutoConfigurationEntry()中获取自动配置信息的主要方法是getCandidateConfigurations(),用于获取候选的自动配置类

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	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;
}

getCandidateConfigurations()中通过ImportCandidates.load方法加载自动配置类的信息。

不过在当前方法中,springboot没有根据传入的参数metadata加载自动配置类,而是固定的向load方法传入AutoConfiguration.class参数,默认加载AutoConfiguration对应的配置文件

public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
	Assert.notNull(annotation, "'annotation' must not be null");
	ClassLoader classLoaderToUse = decideClassloader(classLoader);
	String location = String.format(LOCATION, annotation.getName());
	Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
	List<String> autoConfigurations = new ArrayList<>();
	while (urls.hasMoreElements()) {
		URL url = urls.nextElement();
		autoConfigurations.addAll(readAutoConfigurations(url));
	}
	return new ImportCandidates(autoConfigurations);
}

load()方法中,根据传入的注解反射对象(AutoConfiguration.class)和静态常量LOCATION"META-INF/spring/%s.imports")解析出要加载的配置文件路径META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

在这里插入图片描述

根据路径找到文件,可以看到里面有候选的自动配置类的全限定类名。
springboot会逐行读取这个文件,将信息包装成一个ImportCandidates类型的对象,再将对象中的信息添加到一个List<String>类型的集合中,就获得了候选的自动配置类的全限定类名集合。
springboot会根据这些自动配置类中配置的信息自动注入bean,当然springboot不会全部注入,在获取到这些配置类信息后,还要经过去重、排除、过滤等操作,才能决定最终需要注入的bean。


版权声明:本文为xingyingz原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。