IoC容器初始化过程(二):BeanDefinition载入和注册

BeanDefinition的载入

在IoC容器初始化过程(1)-Resource定位中知道,调用AbstractBeanDefinitionReader中的loadBeanDefinitions方法时不管传入的参数是String类型还是Resource类型,最终都是由XmlBeanDefinitionReader中的loadBeanDefinitions方法实现的,那么就从XmlBeanDefinitionReader开始,看一下载入BeanDefinition的过程。

1.XmlBeanDefinitionReader

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
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {

@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//载入XML形式的资源文件,并使用Resource对象创建EncodedResource对象
return loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
//获取资源对象集合
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
//将当前的资源对象添加到EncodedResource
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
//从EncodedResource获取资源对象的输入流,得到XML文件
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//创建InputSource准备进行读取
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
//设置编码
inputSource.setEncoding(encodedResource.getEncoding());
}
//进行BeanDefinition的载入
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
//移除已经读取过的资源对象
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}

public int loadBeanDefinitions(InputSource inputSource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(inputSource, "resource loaded through SAX InputSource");
}

public int loadBeanDefinitions(InputSource inputSource, @Nullable String resourceDescription)
throws BeanDefinitionStoreException {

return doLoadBeanDefinitions(inputSource, new DescriptiveResource(resourceDescription));
}

/**
* 从XML文件具体载入BeanDefinition的方法
* @param inputSource the SAX InputSource to read from
* @param resource the resource descriptor for the XML file
*/
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//取得XML文件的Document对象
Document doc = doLoadDocument(inputSource, resource);
//注册BeanDefinition
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}

/**
* 向容器中注册BeanDefinition
* 按照Spring的Bean语义要求进行解析资源文件并转换为内部的数据结构BeanDefinition
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建BeanDefinitionDocumentReader用来解析Document,也就是解析XML配置文件
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//具体的解析过程在registerBeanDefinitions方法中完成,该方法在DefaultBeanDefinitionDocumentReader中有实现
int countBefore = getRegistry().getBeanDefinitionCount();
//注册BeanDefinition
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//对载入Bean的数量进行统计
return getRegistry().getBeanDefinitionCount() - countBefore;
}

/**
* 创建BeanDefinitionDocumentReader
* 作用是从XML文件中读取bean信息转为BeanDefinition
*/
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
}

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
//资源文件转为Document对象
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}

}
  • BeanDefinition载入时首先通过DocumentLoader将资源文件转为Document对象,然后使用BeanDefinitionDocumentReader进行解析。
  • BeanDefinitionDocumentReader是一个接口,具体由DefaultBeanDefinitionDocumentReader实现BeanDefinition的注册。

2.DefaultBeanDefinitionDocumentReader

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
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {

/**
* 注册BeanDefinition
*/
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
//获取根节点
Element root = doc.getDocumentElement();
//注册每一个BeanDefinition
doRegisterBeanDefinitions(root);
}

/**
* 根据根节点注册每一个BeanDefinition
*/
protected void doRegisterBeanDefinitions(Element root) {
// 用于解析BeanDefinition的委托类
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);

if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//在开始处理bean定义之前,允许XML通过处理任何自定义元素类型进行扩展
preProcessXml(root);
//从根元素开始解析
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);

this.delegate = parent;
}
/**
* 从根元素开始解析BeanDefinition
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
//获取根节点的所有子节点
NodeList nl = root.getChildNodes();
//遍历根节点的子节点集合
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
//如果是默认的元素
if (delegate.isDefaultNamespace(ele)) {
//解析默认元素
parseDefaultElement(ele, delegate);
}
else {
//解析自定义元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}

/**
* 解析默认的元素(import、alias、bean、beans)
*/
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//解析import
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {//alias
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {//bean
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}

/**
* 处理给定的Element元素,解析BeanDefinition并注册
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 向IoC容器注册解析得到的BeanDefnition
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 注册完成后,发送消息
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
}
  • processBeanDefinition()方法中,使用BeanDefinitionParserDelegate对Element进行解析,返回的是BeanDefinitionHolder对象,用它来完成向IoC容器的注册 。BeanDefinitionHolder是BeanDefinition的封装类,除了BeanDefinition还持有其他与BeanDefinition的使用相关的信息,比如Bean的名字、别名集合等。
  • BeanDefinition生成后,调用了BeanDefinitionReaderUtils的registerBeanDefinition()完成BeanDefinition的注册(注册BeanDefinition的过程会从该方法入手)。

BeanDefinitionHolder

1
2
3
4
5
6
7
8
9
public class BeanDefinitionHolder implements BeanMetadataElement {

private final BeanDefinition beanDefinition;

private final String beanName;

@Nullable
private final String[] aliases;
}

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
129
public class BeanDefinitionParserDelegate {
/**
* 解析XML元素
*/
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}

/**
* 解析元素的详细过程,并返回BeanDefinitionHolder对象
*/
@Nullable
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
*/
@Nullable
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class BeanDefinitionReaderUtils {
/**
* 注册BeanDefinition
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {

// 获取bean的name
String beanName = definitionHolder.getBeanName();
//注册BeanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// 注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
}

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
91
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

/** 存放BeanDefinition对象的Map集合,key为bean的name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

//---------------------------------------------------------------------
// 注册BeanDefinition
//---------------------------------------------------------------------

@Override
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