1、导读
前面已经分析过BeanDefinition在IOC容器中载入和解析过程。在这些动作完成以后,用户定义的BeanDefinition信息已经在IOC容器内建立起了自己的数据结构以及相应的数据表示,但此时这些数据还不能够提供IOC容器直接使用,需要在ioc容器中对这些BeanDefinition数据进行注册。这个注册为ioc容器提供了更友好的使用方式,在DefaultListableBeanFactory中,是通过一个HashMap来持有载入的BeanDefinition的,这个HashMap的定义在DefaultListableBeanFactory中可以看到:
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String,BeanDefinition>();
将得到的BeanDefinition向IOC容器中的beanDefinitionMap注册是在载入BeanDefinition完成后进行的。
2、流程图
3、具体调用过程
在DefaultBeanDefinitionDocumentReader类中完成资源的在载入和解析后会接着调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,this.getReaderContext().getRegistry())方法对资源进行注册,这里传递被解析的资源BeanDefinitionHolder对象以及BeanDefinitionRegistry对象,接着在该方法中会调用BeanDefinitionRegistry类的子类DefaultListableBeanFactory中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)实现方法将解析过后的信息保存到一个线程安全的HashMap对象中。
3.1、DefaultBeanDefinitionDocumentReader类
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if(bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name \'" + bdHolder.getBeanName() + "\'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
3.2、BeanDefinitionReaderUtils类
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if(aliases != null) {
String[] arr$ = aliases;
int len$ = aliases.length;
for(int i$ = 0; i$ < len$; ++i$) {
String aliase = arr$[i$];
registry.registerAlias(beanName, aliase);
}
}
}
3.3、DefaultListableBeanFactory类
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 var7) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var7);
}
}
Map var4 = this.beanDefinitionMap;
BeanDefinition oldBeanDefinition;
synchronized(this.beanDefinitionMap) {
oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
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.");
}
if(this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean \'" + beanName + "\': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
if(oldBeanDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}
}
以上就是关于Spring IOC容器中资源的初始化,在完成了BeanDefinition的注册,就完成了整个IOC容器的初始化过程,在使用的IOC容器中DefaultListableBeanFactory中已经建立了整个Bean的配置信息,而且这些BeanDefinition已经可以被容器所使用了,他们都在beanDefinitionMap里被检索和使用。容器的作用就是对这些信息进行维护和处理。这些信息是依赖反转的基础,有了这些基础数据,下面就可以对IOC容器进行依赖注入了。