配置文件解析完后,剩下的工作就是注册了,是processBeanDefinition函数中的BeanDefinitionReaderUtils.registerBeanDefinition(bdHodler,getReaderContext().getRegistry())代码的解析了。
public static void registryBeanDefinition(BeanDefinitionHolder definitionHolder,BeanDefinitionRegistry registry)
// 使用beanName做唯一标识注册
// 注册所有的别名
1.通过beanName注册BeanDefinition
对于beanName的注册,或许许多人认为的方式就是将beanDefinition直接放入map中就好了,使用beanName作为key,确实spring就是这么做的,除此之外,还做了点别的事。
public void registryBeanDefinition(String beanName,Definition beanDefinition) throws BeanDefinitionStoreException
// 注册前的最后一次校验,这里的校验不同于之前的XML文件校验,主要是对于AbstractBeanDefinition属性中的methodOverrides校验,校验methodOverrides是否与工厂方法并存或者methodOverrides对应方法根本不存在
// 因为beanDefinitionMap是全局变量,这里肯定会存在并发访问的情况
// 处理注册已经注册的beanName情况
// 如果对应的BeanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常
// 记录beanName
// 注册beanDefinition
// 重置所有beanName对应的缓存
}
上面的代码可以看出,对于bean的注册处理方法上,主要进行了几个步骤:
a.对于AbstractBeanDefinition的校验。在解析XML文件的时候,是针对XML格式的校验,而此时的校验时是对于AbstractBeanDefinition的methodOverrides属性的;
b.对beanName已经注册情况的处理。如果没有设置不允许bean的覆盖,则需要抛出异常,否则加入map缓存。
c.清除解析之前留下的对应beanName的缓存。
2.通过别名注册BeanDefinition
在理解了注册bean原理之后,理解别名注册的原理就容易多了。
public void registryAlias(String name,String alisa)
// 如果beanName与alisa相同的话不记录alisa,并删除对应的alisa
// 如果alisa不允许被覆盖则抛异常
}
由以上代码可以得知注册alisa的步骤如下:
a.alisa与beanName相同情况处理,若alisa与beanName并名称相同则不要处理并删除原有alisa;
b.alisa覆盖处理,若alisaName已经使用并已经指向了另一beanName则需要用户的设置进行处理;
c.alisa循环检查,单A->B存在时,若再次出现A->C->B的时候则会抛出异常;注册alis。
标签:beanName,校验,bean,注册,alisa,注解,解析,methodOverrides,BeanDefinition From: https://blog.51cto.com/u_11315052/7535811