导航
导航
文章目录
  1. 一、前言
  2. 二、从BeanDefinitionParserDelegate开始
    1. 2.1 parseBeanDefinitionElement
    2. 2.2 createBeanDefinition
    3. 2.3 GenericBeanDefinition
    4. 2.4 parseBeanDefinitionAttributes
    5. 2.5 parseMetaElements
    6. 2.6 parseLookupOverrideSubElements
    7. 2.7 parseReplacedMethodSubElements
    8. 2.8 parseConstructorArgElements
      1. 2.8.1 自定义解析
      2. 2.8.2 解析bean标签
      3. 2.8.3 解析ref标签
      4. 2.8.4 解析idref标签
      5. 2.8.5 解析value标签
      6. 2.8.6 解析array 标签
      7. 2.8.7 解析list标签
      8. 2.8.8 解析set标签
      9. 2.8.9 解析map标签
      10. 2.8.10 解析props标签
    9. 2.9 parsePropertyElements
    10. 2.10 parseQualifierElements
  3. 三、小结

[断点分析之spring-ioc]-bean标签解析(五)

一、前言

​ 分析了import标签、alias标签,顺势引出了bean标签,只不过bean标签逻辑较为复杂没有记录完.

二、从BeanDefinitionParserDelegate开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// BeanDefinitionParserDelegate
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}

/**
* Parses the supplied {@code <bean>} element. May return {@code null}
* if there were errors during parse. Errors are reported to the
* {@link org.springframework.beans.factory.parsing.ProblemReporter}.
*/
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 获取id
String id = ele.getAttribute(ID_ATTRIBUTE);
// 获取名称
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// 获取别名,别名可以使用多个
List<String> aliases = new ArrayList<>();
// 名称不为空
if (StringUtils.hasLength(nameAttr)) {
// 如果有多个名称,使用,;切割
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
// bean名称就是id
String beanName = id;
// 如果名称为空,并且别名集合不为空,则从别名中获取第一个,作为名称
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isTraceEnabled()) {
logger.trace("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}

if (containingBean == null) {
// 检查beanName是否唯一(名称未被使用过)
checkNameUniqueness(beanName, aliases, ele);
}
// 解析标签封装为beanDefinition
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
// beanDefinition对象不为空
if (beanDefinition != null) {
// beanName为空
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
// 生成bean的 name
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
// 生成bean的 name
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
// 获取 className
String beanClassName = beanDefinition.getBeanClassName();
// 判断bean名称不为空 并且 以类名开头 并且名称没有被使用
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
// 别名集合转为数组
String[] aliasesArray = StringUtils.toStringArray(aliases);
// 返回BeanDefinitionHolder
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}

return null;
}

​ 核心逻辑在于AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);这句代码,进去看看.

2.1 parseBeanDefinitionElement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 // BeanDefinitionParserDelegate
@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
// 放入状态对象到链表中
this.parseState.push(new BeanEntry(beanName));

String className = null;
// 判断是否拥有class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
// 获取className属性值
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
// 判断是否拥有parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
// 获取parent属性值
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建BeanDefinitio对象,封装bean的描述信息
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析bean标签中的各种属性,例如:singleton,scope,abstract等属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 提取描述信息
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析元数据
parseMetaElements(ele, bd);
// 解析lookup-method,相当于动态代理了,可利用此功能来进行热插拔,不用修改代码
// 此功能可以修改方法的返回值
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析replaced-method,此功能可在运行过程中替换掉原有的方法,与lookup-method有点不同
// 要替换需要实现MethodReplacer接口才能替换掉目标方法
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析构造方法参数
parseConstructorArgElements(ele, bd);
// 解析property属性
parsePropertyElements(ele, bd);
// 解析qualifier属性
parseQualifierElements(ele, bd);

bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));

return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
// 弹出解析状态
this.parseState.pop();
}

return null;
}
  1. 判断是否拥有class属性,获取class属性值
  2. 判断是否拥有parent属性,获取parent属性值
  3. 创建AbstractBeanDefinition对象
  4. 解析bean标签中的描述信息,例如:singleton,scope,abstract等属性
  5. 提取描述信息
  6. 解析元数据
  7. 解析lookup-method
  8. 解析replaced-method
  9. 解析构造方法参数
  10. 解析property属性
  11. 解析qualifier属性

大体逻辑如上,以上步骤从步骤3开始进行分析.

2.2 createBeanDefinition

1
2
3
4
5
6
7
// BeanDefinitionParserDelegate
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {

return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// BeanDefinitionReaderUtils
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {

GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
// 加载类
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
// 如果class-loader为空则只记录类名
bd.setBeanClassName(className);
}
}
return bd;
}
  1. 判断类加载器是否为空,如果类加载器不为空则使用指定的类加载器加载类
  2. 返回GenericBeanDefinition对象

以上逻辑比较简单,重点是GenericBeanDefinition这个对象.

2.3 GenericBeanDefinition

GenericBeanDefinition是用于描述bean,该类继承了AbstractBeanDefinition.如下图:

images

​ 总共有2个作用,描述bean的信息,访问bean中的属性值.

2.4 parseBeanDefinitionAttributes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// BeanDefinitionParserDelegate
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
// 解析singleton属性
// singleton属性不能使用,已经过时
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// 判断是否存在scope属性
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
// 设置scope属性值
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
}
// 判断是否存在abstract属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
// 设置abstract属性值
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// 解析lazy-init属性
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
// 设置懒加载值
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
// 获取自动装配属性值
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
// 设置自动装配模式
bd.setAutowireMode(getAutowireMode(autowire));
// 判断是否存在depends-on属性
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
// 获取depends-on属性值
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
// 设置depends-on属性值
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
// 解析autowire属性,自动装配.存在条件判断
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if (isDefaultValue(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
// 设置autowire-candidate属性值
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
// 判断是否存在primary属性
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
// 设置primary值
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
// 判断是否存在init属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
// 获取init属性值
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
// 设置init属性值
bd.setInitMethodName(initMethodName);
}
// 设置init属性默认值
else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
// 判断是否存在destroy属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
// 获取destroy属性值
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
// 设置destroy属性值
bd.setDestroyMethodName(destroyMethodName);
}
// 设置destroy属性默认值
else if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
// 判断是否存在factory属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
// 设置factory属性值
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
// 判断是否存在factory-bean属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
// 设置factory-bean属性值
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}

return bd;
}
  1. 设置BeanDefinition的scope属性值
  2. 设置BeanDefinition的abstract属性值
  3. 设置BeanDefinition的lazy-init属性值
  4. 设置BeanDefinition的autowire属性值
  5. 设置BeanDefinition的depends-on属性值
  6. 设置BeanDefinition的autowire-candidate属性值
  7. 设置BeanDefinition的primary属性值
  8. 设置BeanDefinition的init-method属性值
  9. 设置BeanDefinition的destroy-method属性值
  10. 设置BeanDefinition的factory-method属性值
  11. 设置BeanDefinition的factory-bean的属性值

以上代码就是对BeanDefinition对象的一个属性填充.

2.5 parseMetaElements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// BeanDefinitionParserDelegate
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
// 解析元数据
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
// 解析meta标签
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
Element metaElement = (Element) node;
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
// 使用kv方式创建对象
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(extractSource(metaElement));
// 记录属性
attributeAccessor.addMetadataAttribute(attribute);
}
}
}
1. 遍历所有节点
 2. 解析meta标签
 3. 设置值到attributeAccessor中

2.6 parseLookupOverrideSubElements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	// BeanDefinitionParserDelegate
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
// 获取所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历子节点
Node node = nl.item(i);
// 判断是lookup-method 节点
if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
Element ele = (Element) node;
// 获取name属性 方法名
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
// 获取bean属性 用于替代的bean名称,用于引用bean对象
String beanRef = ele.getAttribute(BEAN_ELEMENT);
// 创建LookupOverride 对象
LookupOverride override = new LookupOverride(methodName, beanRef);
override.setSource(extractSource(ele));
// 添加到overrides对象中的集合中
overrides.addOverride(override);
}
}
}
  1. 遍历所有节点
  2. 获取name属性
  3. 获取bean属性
  4. 创建LookupOverride对象
  5. 添加到MethodOverrides

lookup-method这个东西,相当于是替换一个方法,与replaced-method这个有些许不同.在后面处理bean的时候还会再次出现.

2.7 parseReplacedMethodSubElements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// BeanDefinitionParserDelegate
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
// 获取所有节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历所有节点
Node node = nl.item(i);
// 判断是replaced-method 节点
if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
Element replacedMethodEle = (Element) node;
// 获取name属性
String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
// 获取replacer 属性
String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
// 创建ReplaceOverride 对象
ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
// Look for arg-type match elements.
// 获取arg-type 子节点
List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
// 遍历arg-type 节点
for (Element argTypeEle : argTypeEles) {
// 获取match 属性
String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
// 如果match属性为空 说明有子节点循环遍历子节点值,拼装参数
// 如果match属性不为空 match 值就为本身
match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
if (StringUtils.hasText(match)) {
replaceOverride.addTypeIdentifier(match);
}
}
replaceOverride.setSource(extractSource(replacedMethodEle));
// 添加到集合
overrides.addOverride(replaceOverride);
}
}
}

​ 逻辑与lookup-method处理的差不多.

2.8 parseConstructorArgElements

1
2
3
4
5
6
7
8
9
10
11
12
13
// BeanDefinitionParserDelegate
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
// 获取所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历子节点
Node node = nl.item(i);
// 判断是constructor-arg 节点
if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
parseConstructorArgElement((Element) node, bd);
}
}
}
  1. 遍历所有节点
  2. 查找节点constructor-arg
  3. 解析参数

解析参数的逻辑单独在一个方法中parseConstructorArgElement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// BeanDefinitionParserDelegate
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
// 提取 index 属性
String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
// 提取 type 属性
String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
// 提取 name 属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// 处理 index 属性逻辑
if (StringUtils.hasLength(indexAttr)) {
try {
// 下标转换为 int
int index = Integer.parseInt(indexAttr);
// 下标不允许小于0
if (index < 0) {
error("'index' cannot be lower than 0", ele);
}
else {
try {
this.parseState.push(new ConstructorArgumentEntry(index));
// 解析 properties 属性
Object value = parsePropertyValue(ele, bd, null);
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
// 设置 typeAttr 属性值
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
// 设置 name 属性值
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
// 判断下标是否重复
if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
error("Ambiguous constructor-arg entries for index " + index, ele);
}
else {
// 添加 下标 参数
bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
}
}
finally {
this.parseState.pop();
}
}
}
catch (NumberFormatException ex) {
error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
}
}
else {
// 不包含 index 属性处理逻辑
try {
this.parseState.push(new ConstructorArgumentEntry());
Object value = parsePropertyValue(ele, bd, null);
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
}
finally {
this.parseState.pop();
}
}
}

通过判断是否有index属性来进行解析配置文件.解析参数的代码为parsePropertyValue(ele, bd, null);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// BeanDefinitionParserDelegate
@Nullable
public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) {
String elementName = (propertyName != null ?
"<property> element for property '" + propertyName + "'" :
"<constructor-arg> element");

// Should only have one child element: ref, value, list, etc.
// 获取所有子节点
NodeList nl = ele.getChildNodes();
Element subElement = null;
// 遍历所有子节点
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
// description 节点 和 meta节点 不处理
if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
!nodeNameEquals(node, META_ELEMENT)) {
// Child element is what we're looking for.
if (subElement != null) {
error(elementName + " must not contain more than one sub-element", ele);
}
else {
subElement = (Element) node;
}
}
}
// 判断是够包含 ref 属性
boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
// 判断是否包含 value 属性
boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
// 如果 [[同时包含 ref 属性 和 value 属性] 或者 [[包含 ref 属性 或者 value属性 之一] 并且 subElement 不为空]]
// 则 抛出异常
if ((hasRefAttribute && hasValueAttribute) ||
((hasRefAttribute || hasValueAttribute) && subElement != null)) {
error(elementName +
" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
}
// 处理只包含 ref 属性逻辑
if (hasRefAttribute) {
// 获取 ref 属性值
String refName = ele.getAttribute(REF_ATTRIBUTE);
// 如果 ref 属性值为空 error
if (!StringUtils.hasText(refName)) {
error(elementName + " contains empty 'ref' attribute", ele);
}
// 创建 RuntimeBeanReference 对象
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(extractSource(ele));
return ref;
}
// 处理值包含 value 属性逻辑
else if (hasValueAttribute) {
// 创建 TypedStringValue 对象
TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
valueHolder.setSource(extractSource(ele));
return valueHolder;
}
// 处理只有子元素逻辑
else if (subElement != null) {
return parsePropertySubElement(subElement, bd);
}
// error
else {
// Neither child element nor "ref" or "value" attribute found.
error(elementName + " must specify a ref or value", ele);
return null;
}
}
  1. 遍历所有节点
  2. description 和 meta 节点不处理,跳过.
  3. 判断是否包含 ref 属性
  4. 判断是否包含 value 属性
  5. 处理 ref
  6. 处理 value
  7. 处理子元素

​ 处理逻辑不复杂,复杂点的可能是在处理子元素的实时,相对复杂点.通常子元素的处理就是把值转换为 Map\List\Set等数据结构.处理子元素的方法是parsePropertySubElement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// BeanDefinitionParserDelegate
@Nullable
public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd) {
return parsePropertySubElement(ele, bd, null);
}

/**
* Parse a value, ref or collection sub-element of a property or
* constructor-arg element.
* @param ele subelement of property element; we don't know which yet
* @param bd the current bean definition (if any)
* @param defaultValueType the default type (class name) for any
* {@code <value>} tag that might be created
*/
@Nullable
public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd, @Nullable String defaultValueType) {
// 处理非默认名称空间
if (!isDefaultNamespace(ele)) {
return parseNestedCustomElement(ele, bd);
}
// 处理 bean
else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
if (nestedBd != null) {
nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
}
return nestedBd;
}
// 处理 ref
else if (nodeNameEquals(ele, REF_ELEMENT)) {
// A generic reference to any name of any bean.
// 获取 需要引用的 bean 名称
String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
boolean toParent = false;
// 如果 需要引用的bean 名称为空
if (!StringUtils.hasLength(refName)) {
// A reference to the id of another bean in a parent context.
// 获取 需要引用的parent 属性
refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
toParent = true;
// 如果 bean 为空 并且 parent 属性都为空 则 error
if (!StringUtils.hasLength(refName)) {
error("'bean' or 'parent' is required for <ref> element", ele);
return null;
}
}
// 如果需要引用的 bean 名称 依然为空 则 error
if (!StringUtils.hasText(refName)) {
error("<ref> element contains empty target attribute", ele);
return null;
}
// 创建 RuntimeBeanReference 对象
RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
ref.setSource(extractSource(ele));
return ref;
}
// 处理 idref
else if (nodeNameEquals(ele, IDREF_ELEMENT)) {
return parseIdRefElement(ele);
}
// 处理 value
else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
return parseValueElement(ele, defaultValueType);
}
// 处理 null
else if (nodeNameEquals(ele, NULL_ELEMENT)) {
// It's a distinguished null value. Let's wrap it in a TypedStringValue
// object in order to preserve the source location.
// 创建 TypedStringValue 对象
TypedStringValue nullHolder = new TypedStringValue(null);
nullHolder.setSource(extractSource(ele));
return nullHolder;
}
// 处理 array
else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
return parseArrayElement(ele, bd);
}
// 处理 list
else if (nodeNameEquals(ele, LIST_ELEMENT)) {
return parseListElement(ele, bd);
}
// 处理 set
else if (nodeNameEquals(ele, SET_ELEMENT)) {
return parseSetElement(ele, bd);
}
// 处理 map
else if (nodeNameEquals(ele, MAP_ELEMENT)) {
return parseMapElement(ele, bd);
}
// 处理 props
else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
return parsePropsElement(ele);
}
// error
else {
error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
return null;
}
}

​ 开头就是一个判断,判断是否是默认名称空间,如果非默认名称空间采用自定义解析逻辑.

2.8.1 自定义解析

​ 创建自定义xsd

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="https://onew.me/schema/adv"
targetNamespace="https://onew.me/schema/adv" elementFormDefault="qualified">
<xsd:element name="AdvProp">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="age" type="xsd:string" />
</xsd:complexType>
</xsd:element>

</xsd:schema>

​ 创建类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.sjr.test.bean;

public class AdvProp {

private String name;

private String age;

public String getName() {
return name;
}

public AdvProp setName(String name) {
this.name = name;
return this;
}

public String getAge() {
return age;
}

public AdvProp setAge(String age) {
this.age = age;
return this;
}
}

​ 修改测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.sjr.test.bean;

public class MyTestBean {

private AdvProp advProp;

private String testStr = "test--one";

public MyTestBean(AdvProp advProp) {
this.advProp = advProp;
}

public MyTestBean() {
}

public String getTestStr() {
return testStr;
}

public MyTestBean setTestStr(String testStr) {
this.testStr = testStr;
return this;
}

public AdvProp getAdvProp() {
return advProp;
}

public MyTestBean setAdvProp(AdvProp advProp) {
this.advProp = advProp;
return this;
}

public void printAdvProp(){
System.out.println("advProp: age-" + advProp.getAge() + ",name-" + advProp.getName());
}
}

​ 创建自定义解析类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestAdvPropParser extends AbstractSingleBeanDefinitionParser {

@Override
protected Class<?> getBeanClass(Element element) {
return AdvProp.class;
}

@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
final String name = element.getAttribute("name");
final String age = element.getAttribute("age");
builder.addPropertyValue("name",name);
builder.addPropertyValue("age",age);
}
}

​ 创建自定义NamespaceHandler类

1
2
3
4
5
6
7
public class TestNamespaceHandler extends NamespaceHandlerSupport {

@Override
public void init() {
registerBeanDefinitionParser("AdvProp",new TestAdvPropParser());
}
}

​ 配置spring.handlers

1
https\://onew.me/schema/adv=com.sjr.test.handler.TestNamespaceHandler

​ 配置spring.schemas

1
https\://onew.me/schema/adv/AdvProp.xsd=com/sjr/test/bean/AdvProp.xsd

​ 配置xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:adv="https://onew.me/schema/adv"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
https://onew.me/schema/adv https://onew.me/schema/adv/AdvProp.xsd
">
<bean id="myTestBean" class="com.sjr.test.bean.MyTestBean">
<constructor-arg>
<adv:AdvProp name="testAdv" age="31"/>
</constructor-arg>
</bean>
</beans>

​ 修改测试代码

1
2
3
4
5
6
@Test
public void testSpringAdvParseTag(){
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/sjr/test/bean/AdvTestBean.xml"));
final MyTestBean testBean = factory.getBean("myTestBean",MyTestBean.class);
testBean.printAdvProp();
}

​ 运行结果

1
advProp: age-31,name-testAdv
  1. TestNamespaceHandler用于注册自定义解析器
  2. TestAdvPropParser用于解析自定义标签
  3. spring.schemas用于描述xsd文件路径
  4. spring.handlers用于指定自定义名称空间使用指定的handler

2.8.2 解析bean标签

​ 解析逻辑与bean标签逻辑一致

1
2
3
4
5
6
7
8
9
// BeanDefinitionParserDelegate	
// 处理 bean
else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
if (nestedBd != null) {
nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
}
return nestedBd;
}

2.8.3 解析ref标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// BeanDefinitionParserDelegate
if (nodeNameEquals(ele, REF_ELEMENT)) {
// A generic reference to any name of any bean.
// 获取 需要引用的 bean 名称
String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
boolean toParent = false;
// 如果 需要引用的bean 名称为空
if (!StringUtils.hasLength(refName)) {
// A reference to the id of another bean in a parent context.
// 获取 需要引用的parent 属性
refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
toParent = true;
// 如果 bean 为空 并且 parent 属性都为空 则 error
if (!StringUtils.hasLength(refName)) {
error("'bean' or 'parent' is required for <ref> element", ele);
return null;
}
}
// 如果需要引用的 bean 名称 依然为空 则 error
if (!StringUtils.hasText(refName)) {
error("<ref> element contains empty target attribute", ele);
return null;
}
// 创建 RuntimeBeanReference 对象
RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
ref.setSource(extractSource(ele));
return ref;
}

2.8.4 解析idref标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// BeanDefinitionParserDelegate
@Nullable
public Object parseIdRefElement(Element ele) {
// A generic reference to any name of any bean.
// 获取需要引用的 bean 属性
String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
// 引用的名称为空 则 error
if (!StringUtils.hasLength(refName)) {
error("'bean' is required for <idref> element", ele);
return null;
}
// 引用的名称为空 则 error
if (!StringUtils.hasText(refName)) {
error("<idref> element contains empty target attribute", ele);
return null;
}
// 创建 RuntimeBeanNameReference
RuntimeBeanNameReference ref = new RuntimeBeanNameReference(refName);
ref.setSource(extractSource(ele));
return ref;
}

2.8.5 解析value标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// BeanDefinitionParserDelegate
public Object parseValueElement(Element ele, @Nullable String defaultTypeName) {
// It's a literal value.
// 获取文本值
String value = DomUtils.getTextValue(ele);
// 获取 type 属性
String specifiedTypeName = ele.getAttribute(TYPE_ATTRIBUTE);
String typeName = specifiedTypeName;
// 如果 type 属性为空 则 设置为默认的 type
if (!StringUtils.hasText(typeName)) {
// 默认为 null
typeName = defaultTypeName;
}
try {
// 创建 TypedStringValue 对象
TypedStringValue typedValue = buildTypedStringValue(value, typeName);
typedValue.setSource(extractSource(ele));
typedValue.setSpecifiedTypeName(specifiedTypeName);
return typedValue;
}
catch (ClassNotFoundException ex) {
error("Type class [" + typeName + "] not found for <value> element", ele, ex);
return value;
}
}

2.8.6 解析array 标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	// BeanDefinitionParserDelegate
public Object parseArrayElement(Element arrayEle, @Nullable BeanDefinition bd) {
// 获取 value-type 属性
String elementType = arrayEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
// 获取所有子节点
NodeList nl = arrayEle.getChildNodes();
// 创建 ManagedArray 对象
ManagedArray target = new ManagedArray(elementType, nl.getLength());
target.setSource(extractSource(arrayEle));
target.setElementTypeName(elementType);
target.setMergeEnabled(parseMergeAttribute(arrayEle));
parseCollectionElements(nl, target, bd, elementType);
return target;
}

2.8.7 解析list标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	// BeanDefinitionParserDelegate
public List<Object> parseListElement(Element collectionEle, @Nullable BeanDefinition bd) {
// 获取 value-type 属性
String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
// 获取所有子节点
NodeList nl = collectionEle.getChildNodes();
// 创建 ManagedList 对象
ManagedList<Object> target = new ManagedList<>(nl.getLength());
target.setSource(extractSource(collectionEle));
target.setElementTypeName(defaultElementType);
target.setMergeEnabled(parseMergeAttribute(collectionEle));
parseCollectionElements(nl, target, bd, defaultElementType);
return target;
}

2.8.8 解析set标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	// BeanDefinitionParserDelegate
public Set<Object> parseSetElement(Element collectionEle, @Nullable BeanDefinition bd) {
// 获取 value-type 属性
String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
// 获取所有子节点
NodeList nl = collectionEle.getChildNodes();
// 创建 ManagedSet 对象
ManagedSet<Object> target = new ManagedSet<>(nl.getLength());
target.setSource(extractSource(collectionEle));
target.setElementTypeName(defaultElementType);
target.setMergeEnabled(parseMergeAttribute(collectionEle));
parseCollectionElements(nl, target, bd, defaultElementType);
return target;
}

2.8.9 解析map标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
	// BeanDefinitionParserDelegate
public Map<Object, Object> parseMapElement(Element mapEle, @Nullable BeanDefinition bd) {
// 获取 key-type 属性值
String defaultKeyType = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE);
// 获取 value-type 属性值
String defaultValueType = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE);

// 获取 entry 子节点
List<Element> entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT);
// 创建 ManagedMap 对象
ManagedMap<Object, Object> map = new ManagedMap<>(entryEles.size());
map.setSource(extractSource(mapEle));
map.setKeyTypeName(defaultKeyType);
map.setValueTypeName(defaultValueType);
map.setMergeEnabled(parseMergeAttribute(mapEle));

// 遍历 entryEles 集合
for (Element entryEle : entryEles) {
// Should only have one value child element: ref, value, list, etc.
// Optionally, there might be a key child element.
// 获取子节点
NodeList entrySubNodes = entryEle.getChildNodes();
Element keyEle = null;
Element valueEle = null;
// 遍历 entrySubNodes
for (int j = 0; j < entrySubNodes.getLength(); j++) {
Node node = entrySubNodes.item(j);
if (node instanceof Element) {
Element candidateEle = (Element) node;
// 处理 key 节点逻辑
if (nodeNameEquals(candidateEle, KEY_ELEMENT)) {
if (keyEle != null) {
error("<entry> element is only allowed to contain one <key> sub-element", entryEle);
}
else {
keyEle = candidateEle;
}
}
else {
// 忽略 description 节点
// Child element is what we're looking for.
if (nodeNameEquals(candidateEle, DESCRIPTION_ELEMENT)) {
// the element is a <description> -> ignore it
}
else if (valueEle != null) {
error("<entry> element must not contain more than one value sub-element", entryEle);
}
else {
valueEle = candidateEle;
}
}
}
}

// Extract key from attribute or sub-element.
Object key = null;
// 判断是否包含 key 属性
boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE);
// 判断是否包含 key-ref 属性
boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE);
// 如果 [[包含 key 属性 并且 包含 key-ref 属性] 或者 [[包含 key 属性 或 包含 key-ref 之一]] 并且 keyEle 不为空]
// 则 报错
if ((hasKeyAttribute && hasKeyRefAttribute) ||
(hasKeyAttribute || hasKeyRefAttribute) && keyEle != null) {
error("<entry> element is only allowed to contain either " +
"a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle);
}
// 处理 key 属性
if (hasKeyAttribute) {
key = buildTypedStringValueForMap(entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyType, entryEle);
}
// 处理 key-ref 属性
else if (hasKeyRefAttribute) {
String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
error("<entry> element contains empty 'key-ref' attribute", entryEle);
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(extractSource(entryEle));
key = ref;
}
else if (keyEle != null) {
key = parseKeyElement(keyEle, bd, defaultKeyType);
}
else {
error("<entry> element must specify a key", entryEle);
}

// Extract value from attribute or sub-element.
Object value = null;
// 判断 是否包含 value 属性
boolean hasValueAttribute = entryEle.hasAttribute(VALUE_ATTRIBUTE);
// 判断 是否包含 value-ref 属性
boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE);
// 判断 是否包含 value-type 属性
boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE);
if ((hasValueAttribute && hasValueRefAttribute) ||
(hasValueAttribute || hasValueRefAttribute) && valueEle != null) {
error("<entry> element is only allowed to contain either " +
"'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle);
}
if ((hasValueTypeAttribute && hasValueRefAttribute) ||
(hasValueTypeAttribute && !hasValueAttribute) ||
(hasValueTypeAttribute && valueEle != null)) {
error("<entry> element is only allowed to contain a 'value-type' " +
"attribute when it has a 'value' attribute", entryEle);
}
// 处理 value 属性
if (hasValueAttribute) {
String valueType = entryEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
if (!StringUtils.hasText(valueType)) {
valueType = defaultValueType;
}
value = buildTypedStringValueForMap(entryEle.getAttribute(VALUE_ATTRIBUTE), valueType, entryEle);
}
// 处理 value-ref 属性
else if (hasValueRefAttribute) {
String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
error("<entry> element contains empty 'value-ref' attribute", entryEle);
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(extractSource(entryEle));
value = ref;
}
// 处理 valueEle
else if (valueEle != null) {
value = parsePropertySubElement(valueEle, bd, defaultValueType);
}
else {
error("<entry> element must specify a value", entryEle);
}

// Add final key and value to the Map.
// 添加最终的 key 和 value 到 map 中去
map.put(key, value);
}

return map;
}

转换为map的时候逻辑稍微有点复杂,慢慢看,还是能看懂.

2.8.10 解析props标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
	// BeanDefinitionParserDelegate
public Properties parsePropsElement(Element propsEle) {
// 创建 ManagedProperties 对象
ManagedProperties props = new ManagedProperties();
props.setSource(extractSource(propsEle));
props.setMergeEnabled(parseMergeAttribute(propsEle));

//获取节点下面素有 prop 节点
List<Element> propEles = DomUtils.getChildElementsByTagName(propsEle, PROP_ELEMENT);
// 遍历 prop 节点
for (Element propEle : propEles) {
// 获取 key
String key = propEle.getAttribute(KEY_ATTRIBUTE);
// Trim the text value to avoid unwanted whitespace
// caused by typical XML formatting.
// 获取 值
String value = DomUtils.getTextValue(propEle).trim();
TypedStringValue keyHolder = new TypedStringValue(key);
keyHolder.setSource(extractSource(propEle));
TypedStringValue valueHolder = new TypedStringValue(value);
valueHolder.setSource(extractSource(propEle));
// 放入到 props 对象中
props.put(keyHolder, valueHolder);
}

return props;
}

2.9 parsePropertyElements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// BeanDefinitionParserDelegate	
public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
// 获取所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历 所有节点
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
parsePropertyElement((Element) node, bd);
}
}
}

public void parsePropertyElement(Element ele, BeanDefinition bd) {
// 获取 name 属性
String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
// name 属性为空 则报错
if (!StringUtils.hasLength(propertyName)) {
error("Tag 'property' must have a 'name' attribute", ele);
return;
}
this.parseState.push(new PropertyEntry(propertyName));
try {
// 属性名相同则报错
if (bd.getPropertyValues().contains(propertyName)) {
error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
return;
}
Object val = parsePropertyValue(ele, bd, propertyName);
PropertyValue pv = new PropertyValue(propertyName, val);
parseMetaElements(ele, pv);
pv.setSource(extractSource(ele));
bd.getPropertyValues().addPropertyValue(pv);
}
finally {
this.parseState.pop();
}
}
  1. 遍历所有节点
  2. 使用parsePropertyValue方法处理值(该方法已经写到过)
  3. 把解析到的值放入BeanDefinition中去

2.10 parseQualifierElements

1
2
3
4
5
6
7
8
9
10
11
12
13
	// BeanDefinitionParserDelegate
public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) {
// 获取所有子节点
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历所有子节点
Node node = nl.item(i);
// 处理 qualifier 节点
if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
parseQualifierElement((Element) node, bd);
}
}
}
  1. 遍历所有节点
  2. 通过parseQualifierElement方法处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// BeanDefinitionParserDelegate
public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
// 获取 type 属性
String typeName = ele.getAttribute(TYPE_ATTRIBUTE);
// 如果 type 属性为空 则 error
if (!StringUtils.hasLength(typeName)) {
error("Tag 'qualifier' must have a 'type' attribute", ele);
return;
}
this.parseState.push(new QualifierEntry(typeName));
try {
// 创建 AutowireCandidateQualifier 对象
AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);
qualifier.setSource(extractSource(ele));
// 获取 value 属性
String value = ele.getAttribute(VALUE_ATTRIBUTE);
if (StringUtils.hasLength(value)) {
qualifier.setAttribute(AutowireCandidateQualifier.VALUE_KEY, value);
}
// 获取当前节点下的所有节点
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
// 遍历所有子节点
Node node = nl.item(i);
// 处理 attribute 属性
if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
Element attributeEle = (Element) node;
// 获取 key 属性
String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE);
// 获取 value 属性
String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE);
// key and value is not null
if (StringUtils.hasLength(attributeName) && StringUtils.hasLength(attributeValue)) {
BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
attribute.setSource(extractSource(attributeEle));
qualifier.addMetadataAttribute(attribute);
}
else {
error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
return;
}
}
}
bd.addQualifier(qualifier);
}
finally {
this.parseState.pop();
}
}
  1. 遍历所有节点
  2. 把获取到的kv全部放入到AutowireCandidateQualifier对象中去
  3. BeanDefinition对象设置qualifier属性

三、小结

​ 至此已经创建一了一个完整的AbstractBeanDefinition对象,一个对bean信息的描述对象有了,会转为BeanDefinitionHolder为后续操作作为基础.

支持一下
扫一扫,请我吃颗大白兔奶糖
  • 支付宝扫一扫