目录
一、总览
经过以上的分析,我们知道Document中BeanDefinition的解析是在DefaultBeanDefinitionDocumentReader中进行的,让我们回到DefaultBeanDefinitionDocumentReader的processBeanDefinition方法中,继续分析BeanDefinition解析后的注册过程。在processBeanDefinition方法中,我们可以看到这样一句代码:
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
这里的处理就是将解析得到的BeanDefinition注册到bean工厂中,下面我们来看一看具体的源码。
二、源码分析
BeanDefinitionReaderUtils.registerBeanDefinition源码如下所示:
public class BeanDefinitionReaderUtils {
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// 注册BeanDefinition
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 为bean name注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
}
BeanDefinitionRegistry是一个接口,其中定义了一系列与BeanDefinition注册相关的方法,代码如下:
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* 以beanName注册一个beanDefinition
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefini-tionStoreException;
/**
* 移除beanDefinition
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 获取beanDefinition
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 检查是否存在以beanName为名的beanDefinition
*/
boolean containsBeanDefinition(String beanName);
/**
* 获取所有beanDefinition的名称
*/
String[] getBeanDefinitionNames();
/**
* 获取beanDefinition数目
*/
int getBeanDefinitionCount();
/**
* 检查给定的beanName是否已使用
*/
boolean isBeanNameInUse(String beanName);
}
在我们之前分析的FileSystemXmlApplicationContext中,实际上就是以DefaultListableBeanFactory作为基本的IOC容器的,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,registry.registerBeanDefinition实际调用了DefaultListableBeanFactory中实现的registerBeanDefinition方法,如下:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements Con-figurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** 持有beanDefinition的HashMap */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** 以注册顺序保存BeanDefinition名称 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** 以注册顺序保存手动注册的单例名称 */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
@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");
// 验证beanDefinition,主要是验证beanDefinition重写的方法
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
// 已存在beanDefinition
if (oldBeanDefinition != null) {
// 不允许覆盖则抛出异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
// 注册BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else { // 不存在同名beanDefinition,进行注册
// 判断是否已经开始创建Bean,当getBean时则会开始创建Bean,为保证数据一致,需要进行同步处理
if (hasBeanCreationStarted()) {
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;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else { // 容器还在启动过程中,未开始创建Bean,直接注册BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 如果当前beanDefinition覆盖了原有的beanDefinition或手动注册的单例
// 则重置给定名称的beanDefinition的缓存和以该bean为双亲的beanDefinition
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
}
到这里,BeanDefinition的注册就完成了,DefaultListableBeanFactory中通过Map持有BeanDefinition,这样BeanDefinition就在IOC容器中建立了相应的数据结构,但这些BeanDefinition还是相互独立的,下面就需要进行一步重要的处理:依赖注入。