protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析bean
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//修饰bean
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//注册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));
}
}
剩下来就是第四部了注册bean
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
//获取BeanDefinitionHolder中的beanName
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 aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
DefaultListableBeanFactory中完成了对registerBeanDefinition的实现
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 {
//注册之前的最后一次的检验,这里主要对beanDefinition的methodOverrides属性的校验
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
//beanDefinitionMap是一个全局变了因为需要加一个同步锁
synchronized (this.beanDefinitionMap) {
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
//如果存在已经注册的bean
if (oldBeanDefinition != null) {
//判断是否允许使用相同名称重新注册不同的定义
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
}
else {
//记录保存beanName
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
//注册beanDefinition和对应的beanName
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//如果beanDefinition不是空并且单例对象的缓存包含注册的beanName
if (oldBeanDefinition != null || containsSingleton(beanName)) {
//重置给定bean的所有bean定义高速缓存
resetBeanDefinition(beanName);
}
}
(1)对AbstractBeanDefinition的校验。这里的校验是针对AbstractBeanDefinition的method-Overrided属性的
(2)对beanName已经注册的情况的处理。如果设置了不允许bean的覆盖,则需要抛出异常
(3)加入map缓存
(4)清除解析之前留下的对应beanName的缓存。
beanName对应的BeanDefinition注册完成之后就是注册别名对应的BeanDefinition了
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//如果别名和beanName重复,就删除别名
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
//如果alias不允许覆盖就抛出异常
if (!allowAliasOverriding()) {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null && !registeredName.equals(name)) {
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
//检查别名的循环引用
checkForAliasCircle(name, alias);
//将别名和beanName保存到Map中
this.aliasMap.put(alias, name);
}
}
(1)alias与beanName相同情况处理。若alias与beanName同名称则不需要处理并删除原有alias
(2)alias覆盖处理。若aliasName已经使用并已经指向另一beanName则需要用户的设置进行处理
(3)alias循环检查。当A->B存在时,若再次出现A->B->C时候则会抛出异常
(4)注册alias
5.通知监听器解析以及注册完成
通过getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));完成此工作,这里的实现只为了扩展,当程序开发人员需要对注册BeanDefinition时间进行监听时可以通过注册监听器的方式将处理逻辑写入监听器中。