spring是通过IOC对bean进行管理的,而bean的初始化主要分为两部分:bean的注册和bean的实例化。bean的注册主要是spring通过读取配置文件获取各个bean的信息,并且对这些信息进行注册。spring中提供了BeanFactory对bean进行获取,但是其只是提供了一个简单的查询,真正的注册和管理是在BeanDefinitionRegistry中进行的,上节介绍的BeanDEfinition则是bean对应的信息。在分析其代码前,我们先看下使用到的类及其作用。
涉及的类
AliasRegistry
public interface AliasRegistry {
//注册别名
void registerAlias(String name, String alias);
//删除别名
void removeAlias(String alias);
//判断
boolean isAlias(String name);
//获取所有别名
String[] getAliases(String name);
}
其实现类SimpleAliasRegistry使用map来进行管理,注册的实现逻辑如下:
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
synchronized (this.aliasMap) {
//别名与真实名一致,无意义
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
//注册过且没有变化,返回
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
return;
}
if (!allowAliasOverriding()) {
//不允许别名覆盖,报错
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
}
checkForAliasCircle(name, alias);
//注册
this.aliasMap.put(alias, name);
}
}
}
BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {
// 注册 BeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
// 删除 BeanDefinition
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 获取 BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 是否包含 BeanDefinition
boolean containsBeanDefinition(String beanName);
// 获取所有 BeanDefinition 的名称
String[] getBeanDefinitionNames();
// 获取已经注册 BeanDefinition 的个数
int getBeanDefinitionCount();
// 该 BeanDefinition 是否已经在注册表中使用
boolean isBeanNameInUse(String beanName);
}
继承了AliasRegistry,定义了对BeanDefinition的操作
SingletonBeanRegistry
定义了对单例bean的获取和注册,其中DefaultSingletonBeanRegistry是其一个实现,主要是通过集合对bean进行管理。使用的集合的属性名及作用:
- singletonObjects:单例对象缓存,key-value:bean name --> bean instance
- singletonFactories:单例对应的工厂的缓存,使用工厂来创建单例,bean name --> ObjectFactory
- earlySingletonObjects:之前的单例
- registeredSingletons:以及注册过的单例
- singletonsCurrentlyInCreation:正在创建的单例
- inCreationCheckExclusions:在创建单例的时候,如果该单例正在创建,就不会再创建了,就应该排除掉,如果某个单例在该集合中,则表示该单例正在创建
bean的注册:
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
//判断是否已经注册过了,如果注册过了,则抛出异常
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
//注册
addSingleton(beanName, singletonObject);
}
}
//主要是bean和对象通过map管理
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//注册,如果单例对象为null,则使用 NULL_OBJECT 站位
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
//该单例对象已经注册成功,则需要从工厂集合中移除,后面不需要再次注册
this.singletonFactories.remove(beanName);
//之前注册过的对象也移除
this.earlySingletonObjects.remove(beanName);
//向已经注册的单例集合中添加该实例
this.registeredSingletons.add(beanName);
}
}
获取bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果该单例没有注册过,且正在注册
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//获取该bean对应的工厂,通过工厂了创建还bean
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
DefaultListableBeanFactory
该类实现和继承了两种不同的接口和抽象类,一种是和注册相关的接口和抽象类,一种是和获取bean的接口。其注册bean的基本是先查是否已经注册过,如果注册过判断能否覆盖;没注册过,进行注册
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 ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { //已经注册 if (!isAllowBeanDefinitionOverriding()) { //如果已经注册过该bean,且设置为不允许覆盖 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()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE 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 + "]"); } } //如果允许覆盖,则直接注册,覆盖 this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // 该bean还没注册,检查该工厂的bean创建阶段是否已经开始 synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // 如果仍然在启动注册阶段,则直接注册 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
bean的注册
bean注册主要分为两个部分,一部分是读取配置文件信息到内存的Document,第二部分是对Document的节点进行解析注册。注册的逻辑主要在DefaultBeanDefinitionDocumentReader 中的parseBeanDefinitions方法中
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//解析默认的节点
parseDefaultElement(ele, delegate);
}
else {
//解析自定义节点
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
spring的配置文件中,有两大类的bean的声明,一个是默认的<bean>,还有一种是自定义的声明,这里主要讲一下默认的<bean>的声明。
在解析默认的节点的时候,主要是解析<import>、<alias>、<bean>和<beans>,主要看下是如何解析<bean>的。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析获取bean的各种属性
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//对自定义的标签进行解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册
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的所有节点的属性,会得到一个BeanDefinitionHolder的对象,该对象包含了bean的所有的信息。
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // beanname String beanName = definitionHolder.getBeanName(); //使用 DefaultListableBeanFactory 来注册bean,即把beanName和对应的BeanDefinition 注册到map中 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // 注册别名,调用 SimpleAliasRegistry 的 registerAlias 来注册别名 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
至此,<bean>标签的注册分析完毕。