CMSC 5724 Data Mining and Knowledge Discovery - Lecture 09
- Centroid-based clustering
import 标签解析完毕了,我们一起来看看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程。
在方法 #parseDefaultElement(...) 方法中,如果遇到标签为 bean 时,则调用 #processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 方法,进行 bean 标签的解析。代码如下:
1 | // DefaultBeanDefinitionDocumentReader.java |
整个过程分为四个步骤:
BeanDefinitionParserDelegate#parseBeanDefinitionElement(Element ele, BeanDefinitionParserDelegate delegate)方法,进行元素解析。null,错误由 ProblemReporter 处理。bdHolder 。BeanDefinitionHolder 为持有 name 和 alias 的 BeanDefinition。bdHolder 不为空,则调用 BeanDefinitionParserDelegate#decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder bdHolder) 方法,进行自定义标签处理。BeanDefinitionReaderUtils#registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) 方法,对 bdHolder 进行 BeanDefinition 的注册。BeanDefinitionParserDelegate#parseBeanDefinitionElement(Element ele, BeanDefinitionParserDelegate delegate) 方法,进行 <bean> 元素解析。代码如下:
1 | // BeanDefinitionParserDelegate.java |
这个方法还没有对 bean 标签进行解析,只是在解析动作之前做了一些功能架构,主要的工作有:
<1> 处,解析 id、 name 属性,确定 aliases 集合
<2> 处,检测 beanName 是否唯一。代码如下:
/**
* 已使用 Bean 名字的集合
*
* Stores all used bean names so we can enforce uniqueness on a per
* beans-element basis. Duplicate bean ids/names may not exist within the
* same level of beans element nesting, but may be duplicated across levels.
*/
private final Set<String> usedNames = new HashSet<>();
/**
* Validate that the specified bean name and aliases have not been used already
* within the current level of beans element nesting.
*/
protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
// 寻找是否 beanName 已经使用
String foundName = null;
if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
foundName = beanName;
}
if (foundName == null) {
foundName = CollectionUtils.findFirstMatch(this.usedNames, aliases);
}
// 若已使用,使用 problemReporter 提示错误
if (foundName != null) {
error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement);
}
// 添加到 usedNames 集合
this.usedNames.add(beanName);
this.usedNames.addAll(aliases);
}
这里有必要说下 beanName 的命名规则:
在【Spring源码】IoC之注册BeanDefinitions 提到,Spring 有两种解析 Bean 的方式:
#parseDefaultElement(...) 方法,进行默认标签解析BeanDefinitionParserDelegate#parseCustomElement(...) 方法,进行自定义解析。本文就对这两个方法进行详细分析说明。