上一篇看完了register方法的代码,继续跟后面代码

后面执行refresh方法,代码清单如下:

public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
* 准备刷新上下文,设置其启动日期和活动标志以及执行属性源的任何初始化
*/
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
/**
* 通知子类刷新内部的 bean 工厂
* 得到创建的 DefaultListableBeanFactory 工厂
* DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory
* 接下来对工厂进行初始化
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
/**
* 配置工厂的标准上下文特征
*/
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
/**
* 允许在上下文子类中对 bean 工厂进行后置处理
*
* 当前版本的 Spring 代码中没有任何作用,可能是 Spring 为了在后面的版本中方便扩展
*/
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
/**
* 第一重要的方法
*
* 在上下文中调用工厂处理器方法,注册为 bean
* 在 Spring 的环境中去执行已经被注册的 BeanFactoryPostProcessors
* 注册自定义的 BeanFactoryPostProcessors 和 Spring 内部定义的 BeanFactoryPostProcessors
*
* 比较重要的一个是 ConfigurationClassPostProcessor
* 实例化 AnnotationConfigApplicationContext 时初始化了一个 AnnotatedBeanDefinitionReader
* AnnotatedBeanDefinitionReader 的构造方法中将 ConfigurationClassPostProcessor 注册到 BeanDefinition 中
*/
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
// 注册 BeanPostProcessor,Spring AOP 就是在这里进行注册的
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
// 初始化此上下文的消息源
initMessageSource(); // Initialize event multicaster for this context.
// 初始化应用事件广播器【SpringBoot 的启动源码中与该方法有很大关系】
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
// 在特定的上下文子类中初始化其他特殊 bean
// 当前版本中也是什么都没做
onRefresh(); // Check for listener beans and register them.
// 检查监听器 bean 并注册它们
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
/**
* 第二重要的方法
*
* 实例化所有剩余(非延迟初始化)单例。
*/
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
/**
* 最后一步:发布相应的事件
*/
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources.
/**
* 摧毁已经创建的单例 Bean 以避免悬空资源
*/
destroyBeans(); // Reset 'active' flag.
/**
* 重置 active 属性值
*/
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}  

这里就只讨论两个比较重要的方法,分别是 invokeBeanFactoryPostProcessors 方法和 finishBeanFactoryInitialization 方法

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
                          List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { /**
* 如果有的话,首先调用 BeanDefinitionRegistryPostProcessors
*/
Set<String> processedBeans = new HashSet<>(); /**
* 如果 beanFactory 是 BeanDefinitionRegistry
*
* beanFactory 是 DefaultListableBeanFactory
* DefaultListableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry
*/
if (beanFactory instanceof BeanDefinitionRegistry) {
// 转换成 BeanDefinition 注册器
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// Bean 工厂后置处理器集合
// 存放手动添加的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BeanDefinition 注册器后置处理器集合
/**
* BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor
* 存放所有需要注册的 BeanDefinitionRegistryPostProcessor
*/
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 循环遍历手动添加的 BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 外部扩展的
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 调用 postProcessBeanDefinitionRegistry 方法,不是回调
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 存入集合
registryProcessors.add(registryProcessor);
}
// Spring 内部的
else {
// 存入集合
regularPostProcessors.add(postProcessor);
}
} /**
* 需要保留所有未初始化的常规 bean,以使 bean 工厂后置处理器适用于这些 bean
* 在实现 PriorityOrdered,Ordered 和其余的 BeanDefinitionRegistryPostProcessors 之间分开
*
* 放 Spring 内部的 BeanDefinitionRegistryPostProcessor
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
* 获取 BeanDefinitionRegistryPostProcessor bean 名称
* BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子类
*
* 此时至少包含了一个 ConfigurationClassPostProcessor
* class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
* 名称为 internalConfigurationAnnotationProcessor
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* ConfigurationClassPostProcessor 最重要的类
*/
for (String ppName : postProcessorNames) {
/**
* 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors
*/
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 实例化该 bean,并添加到集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 添加到集合中
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并
registryProcessors.addAll(currentRegistryProcessors);
/**
* 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
*
* 集合中的元素包含 ConfigurationClassPostProcessor
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完成,清空集合数据
// 至少清除包含的 ConfigurationClassPostProcessor
currentRegistryProcessors.clear(); // 获取 BeanDefinitionRegistryPostProcessor bean 名称
// 下面的代码理论上不会执行,只是 Spring 确保初始化过程中没有新的类被添加进来
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
/**
* 接下来,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors
*
* 不在 processedBeans 中且实现了 Ordered 的 BeanDefinitionRegistryPostProcessors
*/
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 实例化该 bean,并添加到集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 添加到集合中
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并
registryProcessors.addAll(currentRegistryProcessors);
/**
* 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完成,清空集合数据
currentRegistryProcessors.clear(); /**
* 最后,调用所有其他 BeanDefinitionRegistryPostProcessors
* 直到不再出现其他 BeanDefinitionRegistryPostProcessors
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 获取 BeanDefinitionRegistryPostProcessor 名称
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class,
true,
false
);
for (String ppName : postProcessorNames) {
// 执行剩下的 BeanDefinitionRegistryPostProcessors
if (!processedBeans.contains(ppName)) {
// 实例化该 bean,并添加到集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并
registryProcessors.addAll(currentRegistryProcessors);
/**
* 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 执行完成,清空集合数据
currentRegistryProcessors.clear();
} /**
* 刚才执行完 ConfigurationClassPostProcessor 的回调
* ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
* 现在调用到目前为止处理的所有 BeanFactoryPostProcessor#postProcessBeanFactory 方法的回调
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
/**
* 调用在上下文实例中注册的工厂处理器
*/
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
} /**
* 获取 BeanFactoryPostProcessor 名称
* 此时至少有两个元素:
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* org.springframework.context.event.internalEventListenerProcessor
*
* 需要保留所有未初始化的常规 bean,以使 bean 工厂后处理器适用于这些 bean
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
/**
* 分隔实现了 PriorityOrdered,Ordered 和其余的 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// 处理过则跳过
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 实现了 PriorityOrdered
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 实现了 Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 普通类
else {
// org.springframework.context.event.internalEventListenerProcessor 是普通类
nonOrderedPostProcessorNames.add(ppName);
}
} /**
* 首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessors
*/
// 排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); /**
* 接下来,调用实现 Ordered 的 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); /**
* 最后,调用所有其他 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/**
* 清除缓存的合并 bean 定义,因为后处理器可能已经修改了原始元数据,例如,替换值中的占位符
*/
beanFactory.clearMetadataCache();
}

这里的 invokeBeanDefinitionRegistryPostProcessors 方法比较重要,跟进去后最后调用的是 processConfigBeanDefinitions 方法。

Spring将处理 BeanDefinition 的工作委托给了 ConfigurationClassPostProcessor  这个辅助类来完成

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {

	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获取容器中注册的所有 BeanDefinition 名称
/**
* AnnotatedBeanDefinitionReader 扫描的 6 个
* 和初始化 Spring 上下文环境时传入的一个配置类
*/
String[] candidateNames = registry.getBeanDefinitionNames(); /**
* 遍历获取需要解析的类
*/
for (String beanName : candidateNames) {
// 获取 BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
/**
* 如果 BeanDefinition 中的 configurationClass 属性为 full 或者 lite,则表示已经处理过了,直接跳过
*/
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 否则判断是否是 @Configuration 注解配置类,加了则通过校验,没加再判断是否加了以下注解
/**
* 如果加了 @Configuration 注解,会在后面再解析其他注解;如果没加,只会单独解析相应的注解
*
* 此时只有传进来的配置类会执行
*/
/**
* candidateIndicators.add(Component.class.getName());
* candidateIndicators.add(ComponentScan.class.getName());
* candidateIndicators.add(Import.class.getName());
* candidateIndicators.add(ImportResource.class.getName());
*/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 有的话就添加到 BeanDefinitionHolder 集合中【此时传入的配置类会添加进集合中】
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
} // 如果没有发现其他的 @Configuration 类就立即返回
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);
}); // Detect any custom bean name generation strategy supplied through the enclosing application context
/**
* 检测通过封闭的应用程序上下文提供的任何自定义 bean 名称生成策略
*/
SingletonBeanRegistry sbr = null;
/**
* 如果 BeanDefinitionRegistry 是 SingletonBeanRegistry 的子类
* 传入的是 DefaultListableBeanFactory 是 SingletonBeanRegistry 的子类
*/
if (registry instanceof SingletonBeanRegistry) {
// 强转
sbr = (SingletonBeanRegistry) registry;
// 没有自定义的 name
if (!this.localBeanNameGeneratorSet) {
// 获取 BeanName 生成器
// SingletonBeanRegistry 中是否包含 beanName 为 internalConfigurationBeanNameGenerator 的对象
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
// 有则使用,没有则使用 Spring 默认的
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
} // environment 为空则初始化为 StandardEnvironment
if (this.environment == null) {
this.environment = new StandardEnvironment();
} // Parse each @Configuration class
// 实例化 ConfigurationClassParser 对象,用于解析每个 @Configuration 类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry); /**
* 定义两个集合
* candidates 集合用于将之前加入的 configCandidates 进行去重,因为可能有重复的配置类
* alreadyParsed 用于判断是否解析过
*/
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**
* 解析
*/
parser.parse(candidates);
/**
* 验证
*
* 主要验证 @Configuration 的 @Bean 方法是否是静态和可覆盖的
* 静态则跳过验证
* @Configuration 类中的实例 @Bean 方法必须可以覆盖才能容纳CGLIB
*/
parser.validate(); // 去重
/**
* 此时加了注解的普通类已经注册完成,包括 @Configuration 配置类
*/
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 移除所有已解析的
configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content
// 读取模型并根据其内容创建 BeanDefinition
if (this.reader == null) {
// 实例化 ConfigurationClassBeanDefinitionReader 阅读器,用于创建 BeanDefinitions
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
} // 加载 BeanDefinitions 存入集合中
this.reader.loadBeanDefinitions(configClasses);
// 全部标记为已处理
alreadyParsed.addAll(configClasses);
// 清空候选者集合,后面保存经过校验存在是配置类的候选者 并且 没有处理过
candidates.clear(); // 处理后工厂内的 BeanDefinition 数量大于处理前的数量
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 处理后 BeanFactory 中 beanDefinitionNames 数据
String[] newCandidateNames = registry.getBeanDefinitionNames();
// 处理前 BeanFactory 中 beanDefinitionNames 数据
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
/**
* alreadyParsed + oldCandidateNames = newCandidateNames
*/
Set<String> alreadyParsedClasses = new HashSet<>();
// 已处理的普通类添加到 alreadyParsedClasses 集合中
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
/**
* 循环遍历处理后的 beanDefinitionNames
*/
for (String candidateName : newCandidateNames) {
// 过滤出处理后的候选者中存在于处理前的候选者,即 alreadyParsed 中候选者
// 为什么不直接遍历 alreadyParsed 集合,而是通过这种方式?
// 可能是 Spring 怕正在处理的时候,又手动添加了新的需要解析的类
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
// 再次检查 BeanDefinition 是否是配置类的候选者 并且 没有处理过
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
// 标记所有候选者已处理完成
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
/**
* 将 ImportRegistry 注册为 bean 以支持 ImportAware 的 @Configuration类
*/
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
} // 如果是 CachingMetadataReaderFactory 的子类,这里会进入判断
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
// 清除外部提供的 MetadataReaderFactory 缓存
// 这是一个无操作的共享缓存,因为它会通过ApplicationContext中被清除
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}  

解析的流程委托给了 ConfigurationClassParser 这个类的parser方法来完成

public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 此时只有我们传入的配置类这一个元素
// 根据 BeanDefinition 的类型做不同的处理
for (BeanDefinitionHolder holder : configCandidates) {
// 获取 BeanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
// 是 AnnotatedBeanDefinition 的子类
if (bd instanceof AnnotatedBeanDefinition) {
/**
* 解析注解对象,并存入 Map<ConfigurationClass, ConfigurationClass> 集合中
* 但是这里的 BeanDefinition 是普通的
* 什么是不普通的呢?比如加了 @Bean 和各种 BeanFactoryPostProcessor 得到的 BeanDefinition 不在这里存放
* 但是在这里解析,只是不存放而已
*/
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
// 是 AbstractBeanDefinition 的子类
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
} else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 延迟导入处理类,执行流程暂时没跟,但是到后面的代码就重复了
this.deferredImportSelectorHandler.process();
}  

继续跟 parse 方法,最后执行的是 processConfigurationClass 方法,代码如下:

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// 判断是否需要跳过
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
} /**
* 是否已存在
*
* Map<ConfigurationClass, ConfigurationClass> configurationClasses
* 是存放类之间相互引入的关系集合
*/
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
// 如果当前类被别的类 @Import,则做如下处理
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
// 否则忽略新导入的配置类; 现有的非导入类会覆盖它
return;
} else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
// 找到显式 beanDefinition,可能替换导入,则删除旧的并使用新的
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
} // Recursively process the configuration class and its superclass hierarchy.
/**
* 递归处理配置类及其超类层次结构
*/
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null); this.configurationClasses.put(configClass, configClass);
}  

这里循环处理配置类,doProcessConfigurationClass 代码如下:

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 是否加了 @Component 注解,@Configuration 注解同样适用
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
/**
* 首先递归处理任何成员(嵌套)类
* 处理内部类
*/
processMemberClasses(configClass, sourceClass);
} // Process any @PropertySource annotations
/**
* 处理 @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");
}
} // Process any @ComponentScan annotations
/**
* 获取 @ComponentScan 注解数据
*
* 处理 @ComponentScan 注解
* 扫描路径下加了 @Component 注解的类,并存入 BeanDefinitionMap 中
*/
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) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
/**
* 扫描 @ComponentScan 路径下符合过滤器和候选者条件的类
* 转换为 BeanDefinitionHolder,并注册到 BeanFactory 中
*
* 可以理解为扫描 @ComponentScan 路径下加了 @Configuration、@Component、@Service 等的类
*/
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
/**
* 检查扫描出来的类当中是否还有 Configuration 类
*/
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
// 获取原始 BeanDefinition
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 检查给定的 BeanDefinition 是否是配置类的候选者
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
} // Process any @Import annotations
// SpringBoot 很多 EnableXXX 都是基于 @Import 注解来实现灵活配置的
/**
* 处理 @Import 注解
* 可以引入 @Configuration 类,ImportSelector 类,ImportBeanDefinitionRegistrar 类
*
* 解析 @Import 注解引入的类,ImportSelector 类、ImportBeanDefinitionRegistrar 类和 @Configuration 类作相应的处理
* ImportSelector 类需要递归处理
* ImportBeanDefinitionRegistrar 类存入 Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars 集合中
* @Configuration 类存入 Map<ConfigurationClass, ConfigurationClass> configurationClasses 集合中
*
* ImportSelector 的实现类可以动态实例化一个 BeanDefinition 到 IOC 容器中
*/
processImports(configClass, sourceClass, getImports(sourceClass), true); // Process any @ImportResource annotations
// 处理 @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);
}
} // Process individual @Bean methods
// 处理每个 @Bean 注解方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
} // Process default methods on interfaces
// 处理接口上的默认方法
processInterfaces(configClass, sourceClass); // Process superclass, if any
// 如果有父类则处理
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
// 排除 java.lang.Object 的父类且不存在于 knownSuperclasses 集合中
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
// 找到超类,返回其注释元数据并递归
return sourceClass.getSuperClass();
}
} // No superclass -> processing is complete
return null;
}  

这里 this.componentScanParser.parse 方法和 processImports 方法都是比较重要的方法,尤其是  processImports 方法。SpringBoot很多EnableXXX注解都是使用了Spring的ImportBeanDefinitionRegistrar 这个类来实现动态注册的,这是Spring提供的扩展点,以后会写一篇详细的博文和示例来说明,这里就先跳过,跟一下 this.componentScanParser.parse 方法:

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
/**
* 此时又实例化了一个 ClassPathBeanDefinitionScanner
* 并没有使用 AnnotationConfigApplicationContext 构造方法中实例化的 ClassPathBeanDefinitionScanner
*/
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); // 获取 BeanName 生成器
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass); scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass)); // 处理代理模型
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
} else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
} scanner.setResourcePattern(componentScan.getString("resourcePattern")); /**
* 遍历 @ComponentScan 中的 includeFilters
* 获取符合组件扫描的条件的类型
* Filter[] includeFilters() default {};
*/
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
} /**
* 遍历 @ComponentScan 中的 excludeFilters
* 获取不符合组件扫描的条件的类型
* Filter[] excludeFilters() default {};
*/
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
} /**
* 获取 @ComponentScan 中的 lazyInit
* 默认不是懒加载
* 如果是懒加载,则修改 BeanDefinitionDefaults 的懒加载属性值为 True,而不是修改 BeanDefinition 的懒加载属性值为 True
* 为后面应用默认值提供便利
* boolean lazyInit() default false;
*/
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
} // 去重存储扫描的包路径
Set<String> basePackages = new LinkedHashSet<>();
/**
* 获取 @ComponentScan 中的 basePackages()
* String[] basePackages() default {};
*/
String[] basePackagesArray = componentScan.getStringArray("basePackages");
// 循环遍历
for (String pkg : basePackagesArray) {
// 处理逗号、分号、回车和换行符
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
/**
* 获取 @ComponentScan 中的 basePackageClasses
* Class<?>[] basePackageClasses() default {};
*/
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
} // 如果没有注明扫描路径,则默认扫描 @Configuration 类所在包及其子包
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
} scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
}); return scanner.doScan(StringUtils.toStringArray(basePackages));
}  

话不多说,scanner.doScan 方法跟进去就完事了

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {

	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 循环扫描 basePackage 路径下的文件,即 @ComponentScan 注解的 value 或 basePackages 值
for (String basePackage : basePackages) {
/**
* 加了注解且符合条件则转换为 BeanDefinition
*
* AnnotatedGenericBeanDefinition 或 ScannedGenericBeanDefinition
* AnnotatedGenericBeanDefinition 和 ScannedGenericBeanDefinition 都是 AbstractBeanDefinition 的子类
* 这里都转换成了 ScannedGenericBeanDefinition
*/
Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) {
// 解析 Scope 属性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 使用 BeanName 生成器获取候选者的 BeanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
/**
* 如果这个类是 AbstractBeanDefinition 的子类
*
* 此时会进入这个判断
*
* public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition
* public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition
* public class GenericBeanDefinition extends AbstractBeanDefinition
*
* 而被 @ComponentScan 注解扫描后的类都变成了 ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition
*
* 基本上都是 AbstractBeanDefinition 的子类
* 即先将 BeanDefinitionDefaults 的值赋给候选 BeanDefinition
*/
if (candidate instanceof AbstractBeanDefinition) {
/**
* 应用如下默认值:
* setLazyInit(lazyInit);
* setAutowireMode(defaults.getAutowireMode());
* setDependencyCheck(defaults.getDependencyCheck());
* setInitMethodName(defaults.getInitMethodName());
* setEnforceInitMethod(false);
* setDestroyMethodName(defaults.getDestroyMethodName());
* setEnforceDestroyMethod(false);
*/
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
/**
* 如果这个类是 AnnotatedBeanDefinition 的子类
*
* ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition 也是 AnnotatedBeanDefinition 的子类
*
* 这个判断也会进,即跑完上一步时已经具有了默认值,但是用户可能单独为这个类配置了注解值
* 再将扫描到的注解值赋给候选 BeanDefinition
*/
if (candidate instanceof AnnotatedBeanDefinition) {
/**
* 处理自定义注解的值
* 包含的注解有 @Lazy,@Primary,@DependsOn,@Role,@Description
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
/**
* 检查给定候选者的 beanName
*
* 1、是否存在于 BeanFactory 中,如果不存在则直接返回为 True
* 2、校验存在的和现有的 BeanDefinition 是否兼容,兼容则返回 False
* 3、抛异常
*
* 此时刚进行扫描,并没有注册到 BeanFactory 中,所以一般会进
*/
if (checkCandidate(beanName, candidate)) {
// 转换为 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 应用代理模式
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
/**
* 由 Bean 的主要名称和别名注册 BeanDefinition
*
* 将 BeanDefinition 加入 Map<String, BeanDefinition>【主名】 和 Map<String, String>【别名】 集合中
*/
registerBeanDefinition(definitionHolder, this.registry);
}
}
} return beanDefinitions;
}  

而 registerBeanDefinition 方法跟进去与我们上一篇探究的代码一样,这里就不再赘述了。

到这里 invokeBeanFactoryPostProcessors 方法就执行完成了,没执行之前 DefaultListableBeanFactory 中的 BeanDefinitionMap 中的数据如下

执行完后,我们的@Service,@Component,@Bean,@Import等注解类都已经注册到 Bean 工厂中

下一篇解析 refresh 中另一个重要的方法 finishBeanFactoryInitialization

在Spring的方法名中包含了很多 Initialization 和 Instantiation 这两个单词,一个是初始化,一个是实例化

BeanPostProcessor 的直接实现类能够干预 Bean 的初始化过程,比如 ApplicationContextAwareProcessor

BeanPostProcessor 的继承类能够干预 Bean 的实例化过程,比如 SmartInstantiationAwareBeanPostProcessor

这个先提一下,以后再详细说,希望坚持写下去。

基于Spring注解的上下文初始化过程源码解析(二)的更多相关文章

  1. 基于Spring注解的上下文初始化过程源码解析(一)

    最近工作之余有时间和精力,加上平时对源码比较感兴趣,就开始啃起了Spring源码.为加深印象写了这篇博客,如有错误,望各位大佬不吝指正. 我看的是Spring5的源码,从同性社区download下来后 ...

  2. Spring系列(五) 容器初始化过程源码

    IoC/DI 的概念 容器是Spring的核心之一(另一个核心是AOP). 有了容器, IOC才可能实现. 什么使IoC? IoC就是将类自身管理的与其由依赖关系的对象的创建/关联和管理交予容器实现, ...

  3. 关于 Spring 中 getBean 的全流程源码解析

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你提出问题,就要给出解决方案! 最近有粉丝小伙伴反馈,与自己的上级沟通总是遇到障碍, ...

  4. Spring IOC容器启动流程源码解析(四)——初始化单实例bean阶段

    目录 1. 引言 2. 初始化bean的入口 3 尝试从当前容器及其父容器的缓存中获取bean 3.1 获取真正的beanName 3.2 尝试从当前容器的缓存中获取bean 3.3 从父容器中查找b ...

  5. Spring IOC 容器预启动流程源码探析

    Spring IOC 容器预启动流程源码探析 在应用程序中,一般是通过创建ClassPathXmlApplicationContext或AnnotationConfigApplicationConte ...

  6. SpringSecurity 初始化流程源码

    SpringSecurity 初始化流程源码 本篇主要讲解 SpringSecurity初始化流程的源码部分,包括核心的 springSecurityFilterChain 是如何创建的,以及在介绍哪 ...

  7. spring MVC cors跨域实现源码解析

    # spring MVC cors跨域实现源码解析 > 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就 ...

  8. spring MVC cors跨域实现源码解析 CorsConfiguration UrlBasedCorsConfigurationSource

    spring MVC cors跨域实现源码解析 spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议 ...

  9. Android笔记--View绘制流程源码分析(二)

    Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...

随机推荐

  1. 跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh

    SpringCloud系列教程 | 第七篇:Spring Cloud Config 配置中心高可用和refresh Springboot: 2.1.6.RELEASE SpringCloud: Gre ...

  2. IPv6 优于 IPv4 的十大功能

    现在是 9102 年,有一个严重的问题,困扰着资深宅男二狗子.那就是偶像团体没新名了.今年开始,偶像团体 XKB48 已经在无法取更多的新名字了,排列组合的所有方式都已经经过了历史长河的洗礼,除非偶像 ...

  3. C++20 的 Modules

    最近看了两篇关于 C++ 20 Modules 很有意思的文章,戳: <Understanding C++ Modules: Part 1: Hello Modules, and Module ...

  4. 数字IC前后端设计中的时序收敛(一)前言

    本文转自:自己的微信公众号<数字集成电路设计及EDA教程> 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具的教程. 为了纪念,同时 ...

  5. Linux命令学习-ls命令

    Linux中,ls命令的全称是list,主要作用是列出当前目录下的清单. 列出Linux根目录下的所有目录 ls / 列出当前目录下所有文件夹和文件 ls 列出当前目录下所有文件夹和文件(包括以&qu ...

  6. c++学习书籍推荐《面向对象程序设计:C++语言描述(原书第2版)》下载

    百度云及其他网盘下载地址:点我 <面向对象程序设计:C++语言描述(原书第2版)>内容丰富,结构合理,写作风格严谨,深刻地论述了c++语言的面向对象编程的各种技术,主要内容包括:面向对象编 ...

  7. 再见Jenkins,从Gitlab代码提交到k8s服务持续交付只需七毛三(走过路过不要错过)

    Gitlab runner 快速搭建CICD pipeline 背景 日常开发中,相信大家已经做了很多的自动化运维环境,用的最多的想必就是利用Jenkins实现代码提交到自动化测试再到自动化打包,部署 ...

  8. [HNOI2011]数学作业 题解

    这道题看着挺难然而其实看破了也挺容易的.首先N极其的大,几乎要炸掉long long ,所以O(n)的算法一定是扑街了,身为一个脑残志坚的OIer,怎能不想到矩阵快速幂优化呢? 有趣的是这道题矩阵有很 ...

  9. 预学第三天:Ge常用t快捷键,码云,Git使用

    目录 Get常用快捷键 码云及Git的使用 Get常用快捷键 git init #创建一个本地的仓库 **gie add test.txt #指定文件添加 ***git add . #当前文件夹下所有 ...

  10. SSRS报表-级联筛选参数刷新后不能默认全选 -问题解决方案

    好久没有写博客了,最近更新完善修复了SSRS报表的一些问题,和大家分享. 问题描述: 报表中,区域->专区->省份->地级市 此四个筛选参数是联动的,在DataSet中前一父级参数作 ...