从@Import浅入Spring配置加载
version:Spring Framework 5.3.x
AbstractApplicationContext
invokeBeanFactoryPostProcessors
通过refresh()
加载完BeanFactoryPostProcessor
后,调用此方法进行BeanFactoryPostProcessor
处理,使用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
进行
PostProcessorRegistrationDelegate
invokeBeanFactoryPostProcessors
1
2
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
- 使用传入的所有
BeanFactoryPostProcessor
进行处理(BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
) - 获取
beanFactory
中的所有BeanDefinitionRegistryPostProcessor
- 处理
PriorityOrdered
级别的BeanDefinitionRegistryPostProcessor
(ConfigurationClassPostProcessor
) - 处理
Ordered
级别的BeanDefinitionRegistryPostProcessor
- 处理普通的
BeanDefinitionRegistryPostProcessor
ConfigurationClass
配置类封装,包含了配置类的各种信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
final class ConfigurationClass {
//配置类源信息
private final AnnotationMetadata metadata;
private final Resource resource;
@Nullable
private String beanName;
//由谁引入
private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
//@Bean装载
private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
private final Map<String, Class<? extends BeanDefinitionReader>> importedResources =
new LinkedHashMap<>();
//ImportBeanDefinitionRegistrar信息
private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
new LinkedHashMap<>();
final Set<String> skippedBeanMethods = new HashSet<>();
......
}
ConfigurationClassPostProcessor
逻辑集中在processConfigBeanDefinitions
方法中,主要使用ConfigurationClassParser
解析配置,使用BeanDefinitionReader
将解析到的BeanDefinition
注册到BeanFactory
中
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {
......
/**
* Derive further bean definitions from the configuration classes in the registry.
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
......
/**
* Build and validate a configuration model based on the registry of
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
......
//创建ConfigurationClassParser解析配置,使用BeanDefinitionReader将解析到的BeanDefinition注册到registry(DefaultListableBeanFactory)中
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
parser.parse(candidates);
parser.validate();
//获取parser中processConfigurationClasses解析出的所有配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//使用BeanDefinitionReader装载所有配置类配置(BeanDefinition)
this.reader.loadBeanDefinitions(configClasses);
......
}
while (!candidates.isEmpty());
......
}
......
}
ConfigurationClassParser
存在大量递归调用,主要是为了处理配置中嵌入配置的情况,比如配置类中的@Bean
方法、@Import
引入新的配置类等。
processConfigurationClass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
......
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
//调用doProcessConfigurationClass方法解析所有可能的配置情况
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
//将configClass放入map中,在ConfigurationClassPostProcessor中会获取所有的配置类进行导入(包括@Import 导入的普通类,ImportSelector导入的类)
this.configurationClasses.put(configClass, configClass);
}
doProcessConfigurationClass
处理配置类,包括@Component
、@PropertySources
、@ComponentScans
、@Import
、@ImportResource
、@Bean
1
2
3
4
5
6
7
8
9
10
11
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
......
//处理 @Import配置
// Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
......
}
collectImports
getImports
调用它,使用递归收集@Import
注解信息(比如@Enable*
注解中的@Import
,而@Enable*
在启动类上)
1
2
3
4
5
6
7
8
9
10
11
12
13
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
throws IOException {
if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName();
if (!annName.equals(Import.class.getName())) {
collectImports(annotation, imports, visited);
}
}
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
}
}
processImports
对收集到的@Import
注解信息进行处理,引入的普通配置类会封装成ConfigurationClass
,ImportSelector
引入的类会转换成普通类最后封装成ConfigurationClass
,最后会在processConfigurationClass
中放入ConfigurationClassParser的变量中保存;而ImportBeanDefinitionRegistrar
则会放入ConfigurationClass
中,最后都会在ConfigurationClassBeanDefinitionReader
进行BeanDefinition
注册。
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
//处理ImportSelector
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
//创建ImportSelector对象,并回调BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, and ResourceLoaderAware 接口
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
//调用selectImports方法获取需要导入的类名,并封装成SourceClass集合
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
//递归调用处理selectImports获取到的类
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
//处理ImportBeanDefinitionRegistrar
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
//创建ImportBeanDefinitionRegistrar对象,并回调BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, and ResourceLoaderAware 接口
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
//将ImportBeanDefinitionRegistrar对象添加到ConfigurationClass中,后面统一通过ImportBeanDefinitionRegistrar将BeanDefinition注册导容器中
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//将普通类封装成ConfigurationClass回调processConfigurationClass方法
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
ConfigurationClassBeanDefinitionReader
loadBeanDefinitionsForConfigurationClass
根据ConfigurationClass
装载所有的配置
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
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
//普通配置类处理
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
//@Bean方法处理
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//文件资源处理
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//ImportBeanDefinitionRegistrar处理
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}