spring-framework 版本:v5.3.19
前面研究了beanDefinition的注册,但也仅仅是注册这一动作。那么在spring容器启动的过程中,是何时/如何装配的?以及装配的bean是如何注入的?
(考虑到xml方式基本不用了以及篇幅问题,所以本篇只看注解方式AnnotationConfigApplicationContext。)
文章目录
- 何时装配
- beanFactoryPostProcessor的执行入口
- ConfigurationClassPostProcessor的注册
- 如何装配
- 主流程
- 解析配置类
- 加载配置类配置的beanDefinition
- 总结
何时装配
beanFactoryPostProcessor的执行入口
实际上@Bean、@ComponentScan、@Import配置的bean装配逻辑是在ConfigurationClassPostProcessor实现的。这个类实现了BeanDefinitionRegistryPostProcessor接口,且又因为该接口继承自BeanFactoryPostProcessor,所以ConfigurationClassPostProcessor就是一个BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor 提供了一个回调方法 postProcessBeanDefinitionRegistry(),可以在这个方法中对 BeanDefinition 进行修改或者添加新的 BeanDefinition。
单从装配上来说,把ConfigurationClassPostProcessor认为是BeanDefinitionRegistryPostProcessor会比BeanFactoryPostProcessor更贴切。虽然BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,但是顾名思义BeanDefinitionRegistryPostProcessor在BeanFactoryPostProcessor基础上增加了BeanDefinitionRegistry的功能。
从这一点入手即可知道@Bean、@ComponentScan、@Import配置的bean就是在执行所有的BeanFactoryPostProcessor这一步骤装配的,调用流程如下。
在实际执行BeanFactoryPostProcessor时,spring容器将具体实现委托给了PostProcessorRegistrationDelegate这个工具类。PostProcessorRegistrationDelegate代码中处理BeanFactoryPostProcessord的代码如下
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//----------遍历spring容器当前已有的beanFactoryPostProcessors---------//
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//-----------执行已注册的 BeanDefinitionRegistryPostProcessor bean--------------//
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//postProcessBeanDefinitionRegistry()方法
//首先先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
//然后执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
//最后执行其他未被扫描到的BeanDefinitionRegistryPostProcessor
// 因为处理的过程中可能会注册新的BeanDefinitionRegistryPostProcessor
// 所以这里用循环确保所有的BeanDefinitionRegistryPostProcessor都会被执行
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//没有实现BeanDefinitionRegistry接口则直接执行执行BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//--------------------------执行已注册的 BeanFactoryPostProcessor bean------------------------------//
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 跟上面一样
// 都是先按 实现了PriorityOrdered接口、实现了Ordered接口、其他 的顺序处理 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 跳过已经执行的BeanFactoryPostProcessor
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
这个方法首先会判断beanFactory是否来自BeanDefinitionRegistry,如果不是则直接执行beanFactory.beanFactoryPostProcessors属性指向的容器本身已有的BeanFactoryPostProcessors,如果是则保证先执行所有的BeanDefinitionRegistryPostProcessor(包括BeanDefinition中注册的)后再执行BeanFactoryPostProcessors(包括BeanDefinition中注册的)。两者的执行都按 本身已有的->BeanDefinition中PriorityOrdered修饰的->BeanDefinition中Ordered修饰的->BeanDefinition中其他未被执行的顺序执行
ConfigurationClassPostProcessor的注册
上面展示了spring容器在启动的过程中是如何执行BeanFactoryPostProcessors的。那么问题来了,ConfigurationClassPostProcessor这个BeanFactoryPostProcessors是spring容器自带的还是BeanDefinition中注册的呢?如果是注册的,那是何时注册的呢?
我们首先排除容器自带的,通过debug代码可以发现当执行invokeBeanFactoryPostProcessors方法时,spring容器自带的BeanFactoryPostProcessors即传进来的beanFactoryPostProcessors参数为空。
既然不是自带的BeanFactoryPostProcessors那就肯定在前面的某一步中,注册了ConfigurationClassPostProcessor这么一个BeanDefinition。
通过debug代码分析可以得知,在执行refresh方法前(甚至在register方法执行前)就已经存在beanName为org.springframework.context.annotation.internalConfigurationAnnotationProcessor的ConfigurationClassPostProcessor bean了。由此可以推断是在AnnotationConfigApplicationContext容器初始化的时候注册的。
查看初始化流程,可以发现创建reader时会执行AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
在AnnotationConfigUtils.registerAnnotationConfigProcessors中会默认注册一些beanDefinition,ConfigurationClassPostProcessor就是在这里注册的
如何装配
主流程
接下来看ConfigurationClassPostProcessor的具体注册beanDefinition的逻辑
ConfigurationClassPostProcessor#registerAnnotationConfigProcessors
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 遍历 BeanDefinition 找到所有的 Configuration 配置类
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 如果CONFIGURATION_CLASS_ATTRIBUTE属性不为空说明已经处理过了,打印日志
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 没有配置类直接返回
if (configCandidates.isEmpty()) {
return;
}
// 配置类按order注解排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// beanName生成器
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
// 环境变量
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 解析 @Configuration class 并注册解析到的bean
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");
// 解析Configuration配置类
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 注册configurationClass 配置的bean
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
// 找出新注册的BeanDefinition再次进入循环
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
说通俗一点就是
1:找到所有配置类
2:解析配置类
3:加载配置类配置的beanDefinition
4:循环23直至没有新的配置类加载
解析配置类
点进去parser.parse(candidates)
最终会来到ConfigurationClassParser#doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 解析成员类
processMemberClasses(configClass, sourceClass, filter);
}
// 解析 @PropertySource 注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 解析 @ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
//最终会调用ClassPathBeanDefinitionScanner.doScan()方法实现beanDefinition的注册
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 解析 @Import 注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 解析 @ImportResource 注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 解析 @Bean 注解(与@Component不同的是这里不会立即注册到beanDefinitionMap中,是在后续的loadBeanDefinition方法才注册)
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 递归接口的默认实现
processInterfaces(configClass, sourceClass);
// 递归父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
return sourceClass.getSuperClass();
}
}
return null;
}
在这一步会解析配置类的 成员类、@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean 以及递归接口默认实现和递归父类,将解析到的结果封装成ConfigurationClass保存到parse.configurationClasses属性,然后再调用reader.loadBeanDefinitions(configClasses)方法实现beanDefintion的加载。
需要注意的是@ComponentScan会在解析这一步的时先将对应的beanDefinition注册到map中了,而@Import、@Bean注解的beanDefinition是在后续的loadBeanDefinitions才注册到map中的。
加载配置类配置的beanDefinition
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions
可以看到,@Import和@Bean配置的bean都在这一步注册了。
上图提到了两次@Import注解,但作用是不一样的。第一次如果这个类是被Import进来的则先注册他自身,第二次是注册他Import过来类。不过这一步最主要也是最常用的还是注册了@Bean注解的bean。
总结
在启动AnnotationConfigApplicationContext容器创建reader时会默认注册一些beanDefinition,其中就包括ConfigurationClassPostProcessor。ConfigurationClassPostProcessor又是一个beanFactoryPostProcessor,所以后续refresh中invokeBeanFactoryPostProcessors方法执行所有BeanFactoryPostProcessor的方法时就会调用ConfigurationClassPostProcessor的相关逻辑实现@Bean、@ComponentScan、@Import配置的bean的装配。
实现大致如下
1:找到所有配置类
2:解析配置类(@ComponentScan在这一步注册)
3:加载配置类配置的beanDefinition(@Import,@Bean在这一步注册)
4:循环23直至没有新的配置类加载
最后的最后
@ComponentScan调用ClassPathBeanDefinitionScanner.doScan()
@Bean调用BeanDefinitionRegistry.registerBeanDefinition()
@Import调用ImportBeanDefinitionRegistrar.registerBeanDefinitions()
实现beanDefinition的注册。