springboot自动配置源码解析

概述

使用springboog的时候引入starter就自动为我们加载,例如我们引入 spring-boot-starter-web 之后,就自动引入了 Spring MVC 相关的 jar 包,从而自动配置 Spring MVC 。

自动装配原理

@SpringBootApplication
@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,
springboot自动配置源码解析_第1张图片

@SpringBootConfiguration:Spring Boot的配置类; 标注在某个类上,表示这是一个Spring Boot的配置类;
@EnableAutoConfiguration:开启自动配置功能;
@ComponentScan : 扫描包 相当于在spring.xml 配置中context:comonent-scan 但是并没有指定basepackage,如果没有 指定spring底层会自动扫描当前配置类所有在的包

@EnableAutoConfiguration

springboot自动配置源码解析_第2张图片
其中@Import({AutoConfigurationImportSelector.class})是重点

通过@import向spring容器注入AutoConfigurationImportSelector类

在这里插入图片描述

EnableAutoConfigurationImportSelector 实现了DeferredImportSelectorSpring内部在解析@Import注解时会调
用getAutoConfigurationEntry方法

getAutoConfigurationEntry方法会调用getCandidateConfigurations方法

// AutoConfigurationImportSelector.java

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    // <1> 加载指定类型 EnableAutoConfiguration 对应的,在 `META-INF/spring.factories` 里的类名的数组
	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;
}

<1> 处,调用 #getSpringFactoriesLoaderFactoryClass() 方法,获得要从 META-INF/spring.factories 加载的指定类型为 EnableAutoConfiguration 类。代码如下:

// AutoConfigurationImportSelector.java

protected Class<?> getSpringFactoriesLoaderFactoryClass() {
	return EnableAutoConfiguration.class;
}

<1> 处,调用 SpringFactoriesLoader#loadFactoryNames(Class factoryClass, ClassLoader classLoader) 方法,加载指定类型 EnableAutoConfiguration 对应的,在 META-INF/spring.factories 里的类名的数组

现在已经知道了自动装配是怎么加载的,那么问题来了,springboot自动装配调用入口在哪里?
这一块属于spring的知识点,提一嘴,使用@import注入的类spring会加载到ioc容器中,然后调用当前导入类的process方法
springboot自动配置源码解析_第3张图片
我们导入的类实现了
在这里插入图片描述
我们看下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()));
			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
					.getAutoConfigurationEntry(annotationMetadata);
			this.autoConfigurationEntries.add(autoConfigurationEntry);
			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
				this.entries.putIfAbsent(importClassName, annotationMetadata);
			}
		}

最终在process方法里边会加载spring.factories文件的自动配置类

你可能感兴趣的:(#,springboot,spring,boot,spring,java)