SpringBoot自动装配

自动装配原理介绍

启动类注解

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@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
11
12
13
14
15
16
17
18
19
20
21

@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
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

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
9
10
11
12
13
14
15
16
17

//返回应考虑的自动配置类名称。 默认情况下,此方法将使用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