Spring Boot自动装配原理源码分析
- 作者: 五速梦信息网
- 时间: 2026年04月04日 13:27
Spring Boot自动装配原理源码分析
1.环境准备
使用IDEA Spring Initializr快速创建一个Spring Boot项目


添加一个Controller类
@RestController
public class HelloController {
@RequestMapping(“hello”)
public String hello() {<br/>
return "hello";<br/>
}<br/>
}
主配置类如下
@SpringBootApplication
public class SpringbootQuickstartApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootQuickstartApplication.class, args);<br/>
}
}
2.注解分析
@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),<br/>
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)<br/>
})
public @interface SpringBootApplication {
@SpringBootApplication
@Configuration
public @interface SpringBootConfiguration {
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
3.自动装配的主角
@EnableAutoConfiguration@AutoConfigurationPackage@Import
(1)、@AutoConfigurationPackage
点进该注解
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
在点进Register,这是一个静态内部类
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());<br/>
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));<br/>
}
}
new PackageImport(metadata).getPackageName()

再看一眼metadata,果然,就是主配置类

因此,这个注解的作用就是将主配置类所在的包作为自动配置包进行管理
(2)、@Import(AutoConfigurationImportSelector.class)
@Import
selectImports
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;<br/>
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);<br/>
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);<br/>
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
getAutoConfigurationEntry
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {<br/>
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;<br/>
}
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 = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
getCandidateConfigurationsxxxAtuoConfiguration

那么这些自动配置类是如何获取的呢,从哪里获取的呢?
getCandidateConfigurations
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations =<br/>
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),<br/>
getBeanClassLoader());<br/>
Assert.notEmpty(configurations, “… …”);
return configurations;
}
loadFactoryNamesFACTORIES_RESOURCE_LOCATIONMETA-INF/spring.factories
public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();<br/>
return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());<br/>
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {<br/>
MultiValueMap<String, String> result = cache.get(classLoader);<br/>
if (result != null) {<br/>
return result;<br/>
}<br/>
try {<br/>
Enumeration<URL> urls = (classLoader != null ?<br/>
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :<br/>
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));<br/>
result = new LinkedMultiValueMap<>();<br/>
while (urls.hasMoreElements()) {<br/>
URL url = urls.nextElement();<br/>
UrlResource resource = new UrlResource(url);<br/>
Properties properties = PropertiesLoaderUtils.loadProperties(resource);<br/>
for (Map.Entry<?, ?> entry : properties.entrySet()) {<br/>
String factoryTypeName = ((String) entry.getKey()).trim();<br/>
for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {<br/>
result.add(factoryTypeName, factoryImplementationName.trim());<br/>
}<br/>
}<br/>
}<br/>
cache.put(classLoader, result);<br/>
return result;<br/>
}<br/>
catch (IOException ex) {<br/>
throw new IllegalArgumentException("Unable to load factories from location [" +<br/>
FACTORIES_RESOURCE_LOCATION + "]", ex);<br/>
}<br/>
}<br/>
spring-boot-autoconfigure-2.2.4.RELEASE.jar/META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=<br/>
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,<br/>
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration
… …
4.类的加载时机
ConditionalOnClass@ConditionaOn xxx

WebMvcAutoConfiguration

相关文章
-
spring cloud feign 调用一直fallback
spring cloud feign 调用一直fallback
- 互联网
- 2026年04月04日
-
Spring Developer Tools 源码分析:二、类路径监控
Spring Developer Tools 源码分析:二、类路径监控
- 互联网
- 2026年04月04日
-
spring get方法 中文(UTF
spring get方法 中文(UTF
- 互联网
- 2026年04月04日
-
Spring Boot中@ConfigurationProperties注解实现原理源码解析
Spring Boot中@ConfigurationProperties注解实现原理源码解析
- 互联网
- 2026年04月04日
-
Spring Boot系列(三):Spring Boot整合Mybatis源码解析
Spring Boot系列(三):Spring Boot整合Mybatis源码解析
- 互联网
- 2026年04月04日
-
Spring Boot入门系列(二十一)如何优雅的设计 Restful API 接口版本号,实现 API 版本控制!
Spring Boot入门系列(二十一)如何优雅的设计 Restful API 接口版本号,实现 API 版本控制!
- 互联网
- 2026年04月04日






