前面我们已经知道了BeanDefiniton基本数据结构在完成解析与载入之后就会成为spring中的内部数据结构 ,但是这时的数据并不能直接被调用,还需要往Ioc容器中注册这些数据
就是我们常见的一种容器-DefaultListableBeanFactory容器中,就是在这个容器中有一个HashMap来持有BeanDefinition数据结构,下面是对这个HashMap的定义
//可以看见这map对象是以beanName为key值,BeanDefinition对象为value的一种结构
//同时也是用一种CurrentHashMap也就是线程同步一个Map集合
private final Map<String, BeanDefinition> beanDefinitionMap = new CurrentHashMap<String, BeanDefinition>();
BeanDefinition中的注册主要的流程就是以下图解
下面这一部分主要的就是将BeanDefintion数据结构注册到ioc容器中的具体代码分析,就是在defaultListableBeanFactory中实现了BeanDefinitionRegistry接口中的registerBeanDefinition方法注册,下面就是对这一方法的源码解析
//注意到抛出异常的类型-BeanDefintionStoreException异常
//同时从beanDefinitionMap集合根据beanName校验是否存在,如果存在再根据是否覆盖,不允许就抛出异常
//BeanDefinitionOverrideException,不存在时就需要添加锁来保证数据的一致性
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)beanDefinition).validate();
} catch (BeanDefinitionValidationException var8) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
}
}
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.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)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
this.beanDefinitionMap.put(beanName, beanDefinition);
//如果是不存在时,那么就需要添加锁确保集合中数据的一致性
} else {
if (this.hasBeanCreationStarted()) {
//在这里可以看见添加关键词synchronized关键词来确保线程同步
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;
this.removeManualSingletonName(beanName);
}
} else {
//这是正常的注册,也就是我们的常规操作
//主要是将bean,BeanDefiniton对象添加进beanDefinitionMap集合中去
//并且将beanName添加进入beanDefinitonNames集合中去
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}
}
标志与流程:完成了BeanDefinition的注册,就完成了Ioc容器的初始化过程
当BeanDefinition完成注册时,DefaultListableFactory已经建立了整个Bean的配置信息,而且这些BeanDefiniiton已经可以被使用了,它们都在beanDefintionMap中被检索和使用,容器的作用就是对这些信息进行处理与维护,这些信息是容器建立依赖反转的基础