您现在的位置是:首页 >其他 >Spring Bean的顺序网站首页其他
Spring Bean的顺序
简介Spring Bean的顺序
之前的文章已经讲过,Spring Bean的创建是通过动态代理实现的,防止浪费篇幅,我们直接看Bean的循环创建代码;
这里我们可以看到 Bean 的创建是通过:
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
// Create Bean Code....
}
Bean的创建顺序其实就是this.beanDefinitionNames的顺序。
可以看出this.beanDefinitionNames又是List<?>类型,所以顺序源自add(obj)的顺序。那this.beanDefinitionNames又是怎么填充的呢?
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 省略部分代码,直接进入BeanName的add过程.....
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 省略后续代码...
}
再追溯一下org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod中使用到
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 省略....
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 省略....
}
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
// 省略...
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
// 省略...
}
继续向下找到具体的地方:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 省略部分代码..
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 省略部分代码....
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
do {
parser.parse(candidates);
parser.validate();
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());
}
this.reader.loadBeanDefinitions(configClasses);
// 省略部分代码...
}
while (!candidates.isEmpty());
// 省略部分代码...
}
至此,我们基本可以看出来,BeanNames的顺序是由org.springframework.context.annotation.ConfigurationClassPostProcessor决定的,而ConfigurationClassPostProcessor由实现了BeanDefinitionRegistryPostProcessor,其核心就是将代码中注册@Configuration注解的类以及经由此配置类注册的Bean解析为BeanDefinition,而这一步是在refresh()的invokeBeanFactoryPostProcessors(beanFactory);完成的。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。