您的位置:首页 > 编程语言 > Java开发

spring源码(5)父子beans标签之间的属性关系

2017-07-28 10:46 218 查看

一、父子beans标签之间的属性关系

回忆之前的一段代码:

protected void doRegisterBeanDefinitions(Element root) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {
return;
}
}

// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(this.readerContext, root, parent);

preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);

this.delegate = parent;
}


这是BeanDefinitionDocumentReader对Document解析的开始,从注释

Any nested <beans> elements will cause recursion in this method


我们知道,任何一个beans标签的解析都会调用这个方法。所以我们也可以说着是对beans标签的解析,参数root就是beans标签。

在这段代码中,又委托BeanDefinitionParserDelegate实例delegate对beans标签进行解析,每次解析一个beans标签,就根据上一个delegate重新创建一个BeanDefinitionParserDelegate对象。

根据上一个delegate重新创建一个BeanDefinitionParserDelegate对象?

protected BeanDefinitionParserDelegate createDelegate(
XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {

BeanDefinitionParserDelegate delegate = createHelper(readerContext, root, parentDelegate);
if (delegate == null) {
delegate = new BeanDefinitionParserDelegate(readerContext, getEnvironment());
delegate.initDefaults(root, parentDelegate);
}
return delegate;
}

public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
this.readerContext.fireDefaultsRegistered(this.defaults);
}

protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
//如果beans标签定义了default-lazy-init属性
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
//如果default-lazy-init是属性值为default
if (DEFAULT_VALUE.equals(lazyInit)) {
//如果上一个delegate的default-lazy-init的属性值不为null,则去上一次的值
lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE;
}
defaults.setLazyInit(lazyInit);
...


在delegate中使用DocumentDefaultsDefinition的实例defaults进行beans标签属性值的保存。

public class DocumentDefaultsDefinition implements DefaultsDefinition {

private String lazyInit;

private String merge;

private String autowire;

private String dependencyCheck;

private String autowireCandidates;

private String initMethod;

private String destroyMethod;

private Object source;
...

}


新建的BeanDefinitionParserDelegate对象delegate会继承上一次delegate的属性。

二、断点测试

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
<beans default-lazy-init="true">
<beans default-lazy-init="default">
<bean name="dog" lazy-init="default" class="com.test.Dog"></bean>
</beans>
</beans>

</beans>


delegate的默认属性(defaults:DocumentDefaultsDefinition)值表:

第一个beans:

序号属性名属性值
1lazyInitfalse
第二个beans:

序号属性名属性值
1lazyInittrue
第三个beans:

序号属性名属性值
1lazyInittrue
bean的lazy-init属性值为true。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息