前言
上篇博文 Spring源码解读(二)Bean创建过程之解析——BeanDefinition 中已经分析了解析BeanDefinition的过程,这篇博文主要分析将BeanDefinition注册到注册表中的过程。
程序入口
上文中有提到这个方法,为了连贯起来,这里再贴一个程序的入口
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition
/**
* 这是一个处理BeanDefinition的方法,其中就包含bean创建过程中两件事
* 1 - 解析bean,创建BeanDefinitionHolder对象
* 2 - 将注册BeanDefinition
* 3 - 发布注册事件
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析bean的属性,得到BeanDefinitionHolder对象
// BeanDefinitionHolder最终会包含bean的所有信息
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 如果bean中有自定义的标签,则对自定义的标签进行解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 上篇博文已经分析了BeanDefinitionHolder的创建过程
// 本篇博文从此处作为切入点,进行分析注册流程
// bean解析完成,注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 发送注册事件
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionReaderutils
是一个对BeanDefinitionReader实现有用的实用方法,如AbstractInterceptorDrivenBeanDefinitionDecorator、AbstractBeanDefinitionParser、ClassPathBeanDefinitionScanner等用于装饰Bean的类都在使用。
registerBeanDefinition方法功能是 为将给定的bean注册到给定的注册表中。
BeanDefinitionRegistry参数 我们这个案例中使用的是 DefaultListabaleBeanFactory实现。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 主beanName
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
// 使用此注册表注册一个新的 BeanDefinition。
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果有别名,注册别名
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
// 为这个bean设置别名
registry.registerAlias(beanName, alias);
}
}
}
DefalutListableBeanFactory
在 Spring源码解读(一)启动流程分析 中多次提到了DefalutListableBeanFactory, 在AbstractApplicationContext的refresh方法调用链中使用AbstractRefreshableApplicationContext#createBeanFactory创建了一个DefalutListableBeanFactorys实现的BeanFactory,这篇主要就是围绕这个类展开。
为什么围绕它展开呢?
通过下图它的继承实现关系图中可以看到,它几乎继承或实现了常见的BeanRegistry和BeanFactory的所有功能,集大成于一身。先熟悉继承实现关系,有助于对调用链的理解。
简单解释一下这些类的作用:
AliasRegistry:定义对alias别名的基础的增删改查。
SimpleAliasRegistry: AliasRegistry接口的实现类,采用map作为alias的全局缓存。
SigletonRegistry: 定义对单例的注册及获取。
BeanFactory: 定义获取bean及bean的各种属性。
DefaultSingletonBeanRegistry: SingletonBeanRegistry接口的实现。
HierarchicalBeanactory: 继承BeanFactory, 增加了对parentFactory的支持。
BeanDefinitionRegistry: 定义对BeanDefinition的各种增删改操作。
FactoryBeanRegistrySupport: 在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理
ConfigurableBeanFactory: 提供配置Factory的各种方法。
ListableBeanFactory: 根据各种条件获取bean的配置清单。
AbstractBeanFactory: 综合FactoryBeanRegistrySupport和ConfigurableBeanFactory 的功能。
AutowireCapableBeanFactory: 提供创建bean、 自动注入、初始化以及应用bean的后处理器。
AbstractAutowireCapableBeanFactory: 综合AbstractBeanFactory 并对接口Autowire CapableBeanFactory 进行实现。
ConfigurableListableBeanFactory: BeanFactory 配置清单,指定忽略类型及接口等。
DefaultListableBeanFactory: 综合上面所有功能,主要是对bean注册后的处理。
注册bean到注册表registerBeanDefinition()
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 断言 参数验证
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// 如果是AbstractBeanDefinition, 验证它是否重写了抽象方法,同时把重写的方法对父类的方法进行覆盖
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// beanDefinitionMap: 使用map存放BeanDefinition,以beanName为key Definition为value
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 这个beanName已经被注册了,下面根据不同的规则 进行处理
// 是否允许覆盖bean,用这个新的bean替换已经注册的旧的bean
if (!isAllowBeanDefinitionOverriding()) {
// 不允许覆盖,抛出异常,beanName冲突
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// 这个bean在程序承担的角色
// 如果应用自己定义的beanName和框架底层的beanName重复, 则覆盖这个应用级别的bean
// 优先保证框架的基础类被注册
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
// 如果是两个不同的beanDefinition, 用新的bean覆盖已经存在从bean
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 注册到注册表中
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 检查这个工厂的 bean 创建阶段是否已经开始,即在此期间是否有任何 bean 被标记为已创建。
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
// 对注册表加锁,在它处理的期间不能再修改启动时集合元素(用于稳定迭代)
synchronized (this.beanDefinitionMap) {
// 注册到注册表
this.beanDefinitionMap.put(beanName, beanDefinition);
// 加当前beanName添加到beanDefinitionNames集合中
List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 从manualSingletonNames中删除这个单例bean的名称
removeManualSingletonName(beanName);
}
}
else {
// 处于启动阶段,直接加入到注册表中
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
// 从manualSingletonNames中删除这个单例bean的名称
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
// 如果这个beanName已经在注册表中了
// 或者单例对象的注册表中同时也有这个beanName
// 重置给定 bean 的所有 bean 定义缓存,包括从它派生的 bean 的缓存
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
此时,bean已经加到到缓存中的注册表中了,注意bean此时还没有被正式创建,只是被加入到了注册表中。