SpringBoot自动装配

自动装配原理介绍

启动类注解

众所周知,这是springboot的启动类的注解

1
2
3
4
5
6
7
8
@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}

@SpringBootApplication

1
2
3
4
5
6
7
8
9
10
@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看作是 @Configuration@EnableAutoConfiguration@ComponentScan 注解的集合。根据 SpringBoot 官网,这三个注解的作用分别是:

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制

  • @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类

  • @ComponentScan: 扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilterAutoConfigurationExcludeFilter

    @EnableAutoConfiguration` 是实现自动装配的重要注解,我们以这个注解入手。

@EnableAutoConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage//将main包下的所欲组件注册到容器中
@Import({AutoConfigurationImportSelector.class})//加载自动装配类 xxxAutoconfiguration
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

Class<?>[] exclude() default {};

String[] excludeName() default {};
}

这个注解最重要的就是 AutoConfigurationImportSelector这个类了

AutoConfigurationImportSelector

AutoConfigurationImportSelector中重要的方法就是这个,主要负责加载自动配置类的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//默认情况下返回的是@EnableAutoConfiguration中的两个属性
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);
}

getAttributes

这个方法返回了@EnableAutoConfiguration中的两个属性

image-20210514093032660

getCandidateConfigurations

1
2
3
4
5
6
7
8
//返回应考虑的自动配置类名称。 默认情况下,此方法将使用SpringFactoriesLoader和getSpringFactoriesLoaderFactoryClass()来加载候选SpringFactoriesLoader 。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
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;
}

filter

这个方法主要是扫描到所有的

image-20210514093526289

去除一些

image-20210514094139509