SpringBoot 2.2.6.RELEASE 自动装配

博文目录


SpringBoot 的核心作用

  • 自动配置, 从而简化配置

@Import 基础

Spring refresh - invokeBeanFactoryPostProcessors - 解析 @Import

SpringBoot 2.2.6.RELEASE 自动配置入口

SpringBoot集成任意框架都是在Application上添加@EnableXxxxx注解, 自动装备也不例外, 使用@EnableAutoConfiguration注解来启动自动配置, 该注解在@SpringBootApplication注解内

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

@SpringBootApplication

@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 {}

@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
}

AutoConfigurationImportSelector

这里由@Import注解引入了一个AutoConfigurationImportSelector配置类, 该类实现了DeferredImportSelector接口, 且覆盖了getImportGroup方法, 返回了一个AutoConfigurationImportSelector.AutoConfigurationGroup类对象

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
	// ...
    public Class<? extends Group> getImportGroup() {
        return AutoConfigurationImportSelector.AutoConfigurationGroup.class;
    }
	// ...
}

AutoConfigurationGroup.process

AutoConfigurationImportSelector有一个内部类AutoConfigurationGroup实现了Group接口, SpringBoot启动时调用其process方法, 内部调用DeferredImportSelector的getAutoConfigurationEntry方法, 内部调用SpringFactoriesLoader.loadFactoryNames方法从所有jar包的"META-INF/spring.factories"文件内读取key为 org.springframework.boot.autoconfigure.EnableAutoConfiguration 的自动配置的Bean的全类名

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()));
	// 获取要自动配置的Bean的列表, AutoConfigurationEntry, 内部有要配置的 List<String> configurations 和 要排除的 Set<String> 
	AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
			.getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);
	this.autoConfigurationEntries.add(autoConfigurationEntry);
	for (String importClassName : autoConfigurationEntry.getConfigurations()) {
		this.entries.putIfAbsent(importClassName, annotationMetadata);
	}
}

AutoConfigurationImportSelector.getAutoConfigurationEntry

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
		AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
	// 获取使用@EnableAutoConfiguration注解指定排除的自动配置类 exclude 和 excludeName
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	// 从所有jar中找 "META-INF/spring.factories", 并从中拿到key为 org.springframework.boot.autoconfigure.EnableAutoConfiguration 的所有配置项, 不仅是 spring 自带的 spring-boot-autoconfigure, 还有 dubbo-spring-boot-autoconfigure, mybatis-spring-boot-autoconfigure, pagehelper-spring-boot-autoconfigure 等等jar包中也有这个key, 所有涉及的自动配置类都会被找到
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	// 移除重复的配置项
	configurations = removeDuplicates(configurations);
	// 获取到要排除的配置项
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	// 检查是否有无效的排除项
	checkExcludedClasses(configurations, exclusions);
	// 自动配置项中移除排除项
	configurations.removeAll(exclusions);
	// 根据各种@Condition条件, 把不需要自动配置的配置类过滤掉
	// # Auto Configuration Import Filters
	// org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
	// org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
	// org.springframework.boot.autoconfigure.condition.OnClassCondition,\
	// org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
	configurations = filter(configurations, autoConfigurationMetadata);
	// 触发 @Import 的监听类 AutoConfigurationImportListener 的 onAutoConfigurationImportEvent 方法
	// # Auto Configuration Import Listeners
	// org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
	// org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Spring Auto-configuration Classes

从 META-INF/spring.factories 中找到指定 key 的 value

// 这两个方法, 从所有jar中的 "META-INF/spring.factories" 中找factoryType指定的key对应的类
SpringFactoriesLoader.loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader)
SpringFactoriesLoader.loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)

AutoConfigurationGroup.selectImports

调用完AutoConfigurationGroup的process方法后, 调用其selectImports方法, 将所有已经处理过的autoConfigurationEntries中的自动配置项重新排除一遍所有过滤项, 然后包装成一个个Entry并排序

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);

	// 主要是根据 Ordered, @Order, @AutoConfigureBefore, @AutoConfigureAfter 等给自动配置类做排序
	return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
			.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
			.collect(Collectors.toList());
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值