Spring方法路径:org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element, String, BeanDefinition)
一、创建用于属性承载的BeanDefinition
BeanDefinition在Spring中有三个实现,RootBeanDefinition,ChildBeanDefinition,和GenericBeanDefinition
父<bean>用rootBeanDefinition,子<bean>用Child承载,GenericBeanDefinition是2.5版本后新增的文件配置属性定义类,是一站式服务类
二、解析各种属性,将配置中的bean属性设置到bd中,源码如下:
public
AbstractBeanDefinition parseBeanDefinitionAttributes(Element
ele
, String
beanName
,
BeanDefinition
containingBean
, AbstractBeanDefinition
bd
) {
if
(
ele
.hasAttribute(
SINGLETON_ATTRIBUTE
)) {
error(
"Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration"
,
ele
);
}
else
if
(
ele
.hasAttribute(
SCOPE_ATTRIBUTE
)) {
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());
}
if
(
ele
.hasAttribute(
ABSTRACT_ATTRIBUTE
)) {
bd
.setAbstract(
TRUE_VALUE
.equals(
ele
.getAttribute(
ABSTRACT_ATTRIBUTE
)));
}
String
lazyInit
=
ele
.getAttribute(
LAZY_INIT_ATTRIBUTE
);
if
(
DEFAULT_VALUE
.equals(
lazyInit
)) {
lazyInit
=
this
.
defaults
.getLazyInit();
}
bd
.setLazyInit(
TRUE_VALUE
.equals(
lazyInit
));
String
autowire
=
ele
.getAttribute(
AUTOWIRE_ATTRIBUTE
);
bd
.setAutowireMode(getAutowireMode(
autowire
));
if
(
ele
.hasAttribute(
DEPENDS_ON_ATTRIBUTE
)) {
String
dependsOn
=
ele
.getAttribute(
DEPENDS_ON_ATTRIBUTE
);
bd
.setDependsOn(StringUtils.tokenizeToStringArray(
dependsOn
,
MULTI_VALUE_ATTRIBUTE_DELIMITERS
));
}
String
autowireCandidate
=
ele
.getAttribute(
AUTOWIRE_CANDIDATE_ATTRIBUTE
);
if
(
""
.equals(
autowireCandidate
) ||
DEFAULT_VALUE
.equals(
autowireCandidate
)) {
String
candidatePattern
=
this
.
defaults
.getAutowireCandidates();
if
(
candidatePattern
!=
null
) {
String[]
patterns
= StringUtils.commaDelimitedListToStringArray(
candidatePattern
);
bd
.setAutowireCandidate(PatternMatchUtils.simpleMatch(
patterns
,
beanName
));
}
}
else
{
bd
.setAutowireCandidate(
TRUE_VALUE
.equals(
autowireCandidate
));
}
if
(
ele
.hasAttribute(
PRIMARY_ATTRIBUTE
)) {
bd
.setPrimary(
TRUE_VALUE
.equals(
ele
.getAttribute(
PRIMARY_ATTRIBUTE
)));
}
if
(
ele
.hasAttribute(
INIT_METHOD_ATTRIBUTE
)) {
String
initMethodName
=
ele
.getAttribute(
INIT_METHOD_ATTRIBUTE
);
if
(!
""
.equals(
initMethodName
)) {
bd
.setInitMethodName(
initMethodName
);
}
}
else
{
if
(
this
.
defaults
.getInitMethod() !=
null
) {
bd
.setInitMethodName(
this
.
defaults
.getInitMethod());
bd
.setEnforceInitMethod(
false
);
}
}
if
(
ele
.hasAttribute(
DESTROY_METHOD_ATTRIBUTE
)) {
String
destroyMethodName
=
ele
.getAttribute(
DESTROY_METHOD_ATTRIBUTE
);
bd
.setDestroyMethodName(
destroyMethodName
);
}
else
{
if
(
this
.
defaults
.getDestroyMethod() !=
null
) {
bd
.setDestroyMethodName(
this
.
defaults
.getDestroyMethod());
bd
.setEnforceDestroyMethod(
false
);
}
}
if
(
ele
.hasAttribute(
FACTORY_METHOD_ATTRIBUTE
)) {
bd
.setFactoryMethodName(
ele
.getAttribute(
FACTORY_METHOD_ATTRIBUTE
));
}
if
(
ele
.hasAttribute(
FACTORY_BEAN_ATTRIBUTE
)) {
bd
.setFactoryBeanName(
ele
.getAttribute(
FACTORY_BEAN_ATTRIBUTE
));
}
return
bd
;
}
三、解析子元素meta属性
四、解析子元素lookup_method属性(获取器注入的配置:Spring特殊的一种方法注入,它是把一个方法声明为返回某种类型的bean,但实际要返回的bean是在配置文件里面配置的,此方法可用在设计有些可热插拔的功能上,解除程序依赖。)
五、解析子元素的replaced_method
六、解析子元素的constructor-arg,源码解析:
遍历所有的节点,也就是提取所有的constructor-arg,然后进行解析。
首先提取constructor-arg上所有的必要的属性(index、type、name)
如果配置了index:
(1)解析constructor-arg的子元素。
(2)使用
ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
(3)将type、name、index属性一并封装在
ConstructorArgumentValues中并添加到当前BeanDefinition的constructorArgumentValues的
IndexedArgumentValue中
如果未配置index:
(1)解析constructor-arg的子元素。
(2)使用
ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
(3)将type、name、index属性一并封装在
ConstructorArgumentValues中并添加到当前BeanDefinition的constructorArgumentValues的
GenericArgumentValue
中
对构造函数中元素的解析,经历了以下过程:
- 略过了description或者meta
- 提取constructor-arg上的ref和value属性,以便于根据规则验证正确性,其规则为在constructor-arg上不存在以下情况:同时既有ref属性,又有value属性;存在ref或者value属性且又有子元素
- ref属性的处理。使用RuntimeBeanReference封装对应的ref名称
- value属性的处理,使用TypedStringValue封装
- 子元素的处理,构造函数中又嵌入了子元素map
七、解析配置的property属性,并将内容封装在BeanDefinition中的propertyValue属性中
八、解析Qualifier属性。
代码经过以上步骤,就完成了xml配置文件到GenericBeanDefinition的转换,xml中的所有配置,都可以在GenericBeanDefinition中找到配置