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

来源:互联网 发布:虚拟制造软件 编辑:程序博客网 时间:2024/06/14 23:58

一、父子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:

序号 属性名 属性值 1 lazyInit false

第二个beans:

序号 属性名 属性值 1 lazyInit true

第三个beans:

序号 属性名 属性值 1 lazyInit true

bean的lazy-init属性值为true。

原创粉丝点击