上一篇文章讲到解析XML的parseBeanDefinitions(root, this.delegate)方法,首先看看源码
此处isDefaultNamespace方法是获取namespace为http://www.springframework.org/schema/beans的node,可以看到,这里是循环循环处理节点,咱们来看我标红的那行,
可以看到目前对应schema定义的包括”bean”“alis” “beans” “import” ,处理方法为parseDefaultElement(ele, delegate),因为咱们关注的是spring如何管理bean,因此咱们看下processBeanDefinition(ele, delegate);
这里有两个比较关键的步骤
咱们先看如何第一步转换的过程,整个方法太长,我帖出关键代码
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
......
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
.......
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
.......
}
这里有两个关键点:
再来看看如何注册BeanFactory,追寻这个方法往下看看是如何进行注册的
进入这个注册方法会发现进入了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 {
((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);
//这里判断bean是否已经注册过
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 + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {//新注册的类进入下面的逻辑进行处理
if (hasBeanCreationStarted()) {//如果已经有类创建过
// Cannot modify startup-time collection elements anymore (for stable iteration)
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 {
//储存bean信息
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
这里能看到,BeanFactory的实现类中储存了beanName及beanDefinition,那么beanDefinition中保存的又是什么呢?
首先咱们先看些它的来源,顺着代码往回找发现这里的beanDefinition其实是通过Element(我前面有提到)转换得到的,然后咱们再来看看他的定义,这里我把接口的主要方法贴出来
通过这些方法就能很明显的看到BeanDefinition是用来保存bean的各种信息如:父类名、className、scope、依赖关系等等信息
OK,也就是说spring在解析了配置文件之后主要干了两件事
那咱们接着往下看
Engine engine = (Engine)beanFactory.getBean("engine");
如何通过getBean获取bean对象呢?且看下回分解