默认标签的解析
1 | //DefaultBeanDefinitionDocumentReader |
2 | private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { |
3 | if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { |
4 | //import 标签解析 |
5 | importBeanDefinitionResource(ele); |
6 | } |
7 | else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { |
8 | // alias 标签解析 |
9 | processAliasRegistration(ele); |
10 | } |
11 | else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { |
12 | //bean 标签解析 |
13 | processBeanDefinition(ele, delegate); |
14 | } |
15 | else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { |
16 | // recurse |
17 | // beans 标签的解析 |
18 | doRegisterBeanDefinitions(ele); |
19 | } |
20 | } |
bean 标签的解析及注册
- import , alias,bean, beans 标签中,bean标签的解析最为复杂,现在分析bean标签的解析。
1
//DefaultBeanDefinitionDocumentReader
2
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
3
//bdholder 实例中包含了我们配置文件的各种属性了:class ,name, alias
4
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
5
if (bdHolder != null) {
6
// 若默认标签的子节点下再有自定义属性,还需要对自定义属性进行解析
7
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
8
try {
9
//BeanDefinitionHolder 中包含了beanName,和BeanDefinintion
10
//注册beanDefintion 到BeanDefinitionRegistry中,key: beanname,value:BeanDefinition
11
// Register the final decorated instance.
12
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
13
}
14
catch (BeanDefinitionStoreException ex) {
15
getReaderContext().error("Failed to register bean definition with name '" +
16
bdHolder.getBeanName() + "'", ele, ex);
17
}
18
//通知简体器bean已经加载完毕。
19
// Send registration event.
20
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
21
}
22
}
解析BeanDefinition
- BeanDefinitionHolder 获取:
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
1
//BeanDefinitionParserDelegate
2
3
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
4
//解析id属性
5
String id = ele.getAttribute(ID_ATTRIBUTE);
6
// 解析name属性
7
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
8
//别名,多个用 "," 分割
9
List<String> aliases = new ArrayList<>();
10
if (StringUtils.hasLength(nameAttr)) {
11
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
12
aliases.addAll(Arrays.asList(nameArr));
13
}
14
// 设置beanName,如果id为空,如果BeanName则取aliases的第一个值
15
String beanName = id;
16
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
17
beanName = aliases.remove(0);
18
if (logger.isDebugEnabled()) {
19
logger.debug("No XML 'id' specified - using '" + beanName +
20
"' as bean name and " + aliases + " as aliases");
21
}
22
}
23
if (containingBean == null) {
24
checkNameUniqueness(beanName, aliases, ele);
25
}
26
// 01
27
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
28
if (beanDefinition != null) {
29
if (!StringUtils.hasText(beanName)) {
30
try {
31
if (containingBean != null) {
32
beanName = BeanDefinitionReaderUtils.generateBeanName(
33
beanDefinition, this.readerContext.getRegistry(), true);
34
}
35
else {
36
beanName = this.readerContext.generateBeanName(beanDefinition);
37
// 如果不存在beanName 那么根据Spring 提供的命名规则为当前的bean生成对应的beanName
38
// Register an alias for the plain bean class name, if still possible,
39
// if the generator returned the class name plus a suffix.
40
// This is expected for Spring 1.2/2.0 backwards compatibility.
41
String beanClassName = beanDefinition.getBeanClassName();
42
if (beanClassName != null &&
43
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
44
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
45
aliases.add(beanClassName);
46
}
47
}
48
if (logger.isDebugEnabled()) {
49
logger.debug("Neither XML 'id' nor 'name' specified - " +
50
"using generated bean name [" + beanName + "]");
51
}
52
}
53
catch (Exception ex) {
54
error(ex.getMessage(), ele);
55
return null;
56
}
57
}
58
String[] aliasesArray = StringUtils.toStringArray(aliases);
59
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
60
}
61
return null;
62
}
AbstractBeanDefinition 包含每个bean中都有的基础信息
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
1
////BeanDefinitionParserDelegate
2
3
public AbstractBeanDefinition parseBeanDefinitionElement(
4
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
5
this.parseState.push(new BeanEntry(beanName));
6
//解析class属性
7
String className = null;
8
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
9
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
10
}
11
// 解析partent 属性
12
String parent = null;
13
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
14
parent = ele.getAttribute(PARENT_ATTRIBUTE);
15
}
16
try {
17
// 创建承载属性的GenericBeanDefinition(父类为AbstractBeanDefinition)
18
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
19
//硬编码解析bean的各种属性
20
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
21
//提取描述信息
22
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
23
// 解析 mata 元数据
24
parseMetaElements(ele, bd);
25
//解析Lookup—method 属性
26
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
27
//解析replaced-method 属性
28
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
29
// 解析 constructor-arg 属性
30
parseConstructorArgElements(ele, bd);
31
// 解析property 属性
32
parsePropertyElements(ele, bd);
33
//解析 qualifier 属性
34
parseQualifierElements(ele, bd);
35
bd.setResource(this.readerContext.getResource());
36
bd.setSource(extractSource(ele));
37
return bd;
38
}
39
catch (ClassNotFoundException ex) {
40
error("Bean class [" + className + "] not found", ele, ex);
41
}
42
finally {
43
this.parseState.pop();
44
}
45
return null;
46
}
BeanDefinition (interface)继承关系
各种标签
- mata标签
- lookup-method
- replaced-method
- constructor-arg
- property
- qualifier
AbstractBeanDefinition
- 定义了一些标签的配置信息和取值范围。
注册BeanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
1
//BeanDefinitionReaderUtils
2
public static void registerBeanDefinition(
3
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
4
throws BeanDefinitionStoreException {
5
// Register bean definition under primary name.
6
String beanName = definitionHolder.getBeanName();
7
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
8
9
// Register aliases for bean name, if any.
10
String[] aliases = definitionHolder.getAliases();
11
if (aliases != null) {
12
for (String alias : aliases) {
13
registry.registerAlias(beanName, alias);
14
}
15
}
16
}
通知监听器解析及注册完成
1 | //通知简体器bean已经加载完毕。 |
2 | // Send registration event. |
3 | getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); |
该方法为空,项目中如果对bean 的加载需要监控,则需要拓展该方法,spring 自身没有对该方法做任何处理。