BeanDefinition的载入
在IoC容器初始化过程(1)-Resource定位中知道,调用AbstractBeanDefinitionReader中的loadBeanDefinitions方法时不管传入的参数是String类型还是Resource类型,最终都是由XmlBeanDefinitionReader中的loadBeanDefinitions方法实现的,那么就从XmlBeanDefinitionReader开始,看一下载入BeanDefinition的过程。
1.XmlBeanDefinitionReader
1 | public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { |
- BeanDefinition载入时首先通过DocumentLoader将资源文件转为Document对象,然后使用BeanDefinitionDocumentReader进行解析。
- BeanDefinitionDocumentReader是一个接口,具体由DefaultBeanDefinitionDocumentReader实现BeanDefinition的注册。
2.DefaultBeanDefinitionDocumentReader
1 | public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { |
- processBeanDefinition()方法中,使用BeanDefinitionParserDelegate对Element进行解析,返回的是BeanDefinitionHolder对象,用它来完成向IoC容器的注册 。BeanDefinitionHolder是BeanDefinition的封装类,除了BeanDefinition还持有其他与BeanDefinition的使用相关的信息,比如Bean的名字、别名集合等。
- BeanDefinition生成后,调用了BeanDefinitionReaderUtils的registerBeanDefinition()完成BeanDefinition的注册(注册BeanDefinition的过程会从该方法入手)。
BeanDefinitionHolder
1 | public class BeanDefinitionHolder implements BeanMetadataElement { |
3.BeanDefinitionParserDelegate
BeanDefinitionParserDelegate是具体解析XML中的元素与生成BeanDefinition的地方。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
129public class BeanDefinitionParserDelegate {
/**
* 解析XML元素
*/
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
/**
* 解析元素的详细过程,并返回BeanDefinitionHolder对象
*/
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//获取<bean>元素中定义的属性值
String id = ele.getAttribute(ID_ATTRIBUTE);//获取ID属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);//获取name属性
//别名
List<String> aliases = new ArrayList<>();
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 (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//对Bean元素的详细解析,生成BeanDefinition
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
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.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("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);
//对BeanDefinition封装返回BeanDefinitionHolder
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
/**
* 解析元素生成BeanDefinition
*/
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建BeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);//解析attributes元素
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
parseMetaElements(ele, bd);//解析meta元素
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);//解析Property元素
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;
}
}
在parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean)中生成了BeanDefinition对象。然后进行了一系列的解析XML元素的方法,设置到BeanDefinition中,最后将创建的BeanDefinition返回,完成BeanDefinition的载入。
BeanDefinition的注册
BeanDefinition的载入过程中,在DefaultBeanDefinitionDocumentReader中创建BeanDefinition后调用了BeanDefinitionReaderUtils对BeanDefiniton进行注册。
1.BeanDefinitionReaderUtils
1 | public class BeanDefinitionReaderUtils { |
BeanDefinitionRegistry是一个接口,registerBeanDefinition方法由它的子类DefaultListableBeanFactory实现。
2.DefaultListableBeanFactory
在DefaultListableBeanFactory可以看到有一个beanDefinitionMap成员变量,每一个BeanDefinition都会注册到该集合中,IoC容器通过这个HashMap来持有这些BeanDefinition数据。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
91public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** 存放BeanDefinition对象的Map集合,key为bean的name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//---------------------------------------------------------------------
// 注册BeanDefinition
//---------------------------------------------------------------------
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;
//检查是不是有相同名字的BeanDefinition已经在IoC容器中注册了,如果有相同的BeanDefinition,但又不允许覆盖,会抛出异常
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
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()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
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()) {//是否已经启动注册
// 使用synchronized保持数据的一致性
synchronized (this.beanDefinitionMap) {
//注册BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
//注册BeanDefinition,将解析后BeanDefinition放入map,key为bean name,value为BeanDefinition对象
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
}
参考:
spring技术内幕:深入解析spring架构与设计原理
Spring版本:5.0.5