springboot的自动装配原理

发布于:2025-04-19 ⋅ 阅读:(25) ⋅ 点赞:(0)

Spring Boot的自动装配机制通过约定优于配置的原则,极大地简化了Spring应用的开发,同时保持了高度的灵活性和可定制性。

入口注解@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

自动装配的核心是@SpringBootApplication注解中的@EnableAutoConfiguration

@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration

通过@Import(AutoConfigurationImportSelector.class)导入自动配置类选择器

AutoConfigurationImportSelector

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

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

}

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

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation,
				getBeanClassLoader());
		List<String> configurations = importCandidates.getCandidates();
		Assert.notEmpty(configurations,
				"No auto configuration classes found in " + "META-INF/spring/"
						+ this.autoConfigurationAnnotation.getName() + ".imports. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

AutoConfigurationImportSelector类实现了DeferredImportSelector接口,其核心方法selectImports负责加载所有符合条件的自动配置类。

加载逻辑

  • 从类路径下扫描META-INF/spring.factories(旧版)或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(新版)文件,读取org.springframework.boot.autoconfigure.EnableAutoConfiguration键对应的配置类全限定名。
  • 结合条件注解(如@ConditionalOnClass)过滤配置类,仅加载满足条件的配置。

自动装配流程

  1. 启动阶段:Spring Boot扫描@SpringBootApplication主类,触发@EnableAutoConfiguration
  2. 加载配置类:通过AutoConfigurationImportSelector读取spring.factories文件,获取候选配置类。
  3. 条件过滤:根据@Conditional系列注解筛选有效配置类。
  4. Bean注册:符合条件的配置类中的@Bean方法被调用,Bean注册到容器。

Spring Boot通过spring.factories文件实现SPI机制,允许第三方Starter模块声明自动配置类。这种机制实现了“对扩展开放,对修改封闭”的原则。

小技巧

可以通过设置debug=true来查看哪些自动配置类生效,哪些没有生效


网站公告

今日签到

点亮在社区的每一天
去签到