第6讲:BeanDefinitionParserDelegate与资源解析

第五讲的代码块4:registerBeanDefinitions(doc, resource)的内部代码块2的最后已经提到了BeanDefinitionParserDelegate才是真正用于解析BeanDefinition的,下面我们来详解下这个类

1、简述这个类的作用:

这个类是真正解析BeanDefiniton的类(它是一个被委托的类):

属性:它里面的属性定义了要解析的xml文件中出现的所有名字,如:

元素名、属性名等。如:String NAME_ATTRIBUTE = "name";String BEAN_ELEMENT = "bean";String ID_ATTRIBUTE = "id";String CLASS_ATTRIBUTE = "class";等

方法:当然它里面还定义了一系列操作BeanDefinition的方法:如:

parseBeanDefinitionElement()方法解析出BeanDefinition

因为只有把这些信息都注册到这个类中,这个类才能使用这些属性,很方便的解析BeanDefinition嘛。

 

2、该类中用到了两个设计模式:

委托设计模式,委托类负责执行真正的操作之前的一系列准备操作,真正的操作是交给被委托类处理的

模板方法模式:

1、createHelper

2、populateDefaults

3、DocumentDefaultDefinition

 

registerBeanDefinitions(Document doc, XmlReaderContext readerContext)

/**
	 * This implementation parses bean definitions according to the "spring-beans" XSD
	 * (or DTD, historically).
	 * <p>Opens a DOM Document; then initializes the default settings
	 * specified at the {@code <beans/>} level; then parses the contained bean definitions.
	 */
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
             //设置ReaderContext(具体作用不详)
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
           //得到Document中的根元素,也就是<beans>标签,因为只要获取到了根元素,就能通过根元素获取到其他任何子元素和属性。这点和js中的document对象类型
		Element root = doc.getDocumentElement();
           //真正注册BeanDefinition的方法(详解见:代码块1)
		doRegisterBeanDefinitions(root);
	}

代码块1:doRegisterBeanDefinitions(root)

 

/**
	 * Register each bean definition within the given root {@code <beans/>} element.
	 */
	protected void doRegisterBeanDefinitions(Element root) {
		// 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.
   
           //任何嵌套的<beans>元素都会在这个方法中引起递归。在
            //为了正确地传播和保存<beans> default-*属性,
            //跟踪当前(父)委托,可能为空。创建
            //新的(子)委托,它有一个对父类的引用,
            //然后最终将this.delegate重置为其原始(父)引用。
            //这个行为模拟了一堆委托,但实际上并不需要一个。
            
            //也就是说这里会出现递归调用的可能(具体是这个方法会递归调用,还是这个方法里面有递归调用暂时不清楚)
            //看上面的翻译,当存在一个<beans>中嵌套<beans>时会导致递归。为什么会出现<beans>中包含<beans>的情况呢?因为spring配置文件支持:一个配置文件引入另一个配置文件。
		
            //先将当前的BeanDefinitionParserDelegate保存到一个新的变量,parent代表子<beans>的父<beans>
            BeanDefinitionParserDelegate parent = this.delegate;
            //创建新的BeanDefinitionParserDelegate  (详解见:内部代码块1)
		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;
				}
			}
		}
              //这里用到了模板方法的设计模式
            //是spring框架设计出的一个扩展点,默认preProcessXml()和postProcessXml()只提供空方法,具体实现又开发人员根据自己业务的需求自己在子类中重写此方法
            //一般这两个方法的作用是:当我们在xml自定义元素时(不是spring里面规定的元素,而是可能为了实现某种功能,我们自己编写的元素,spring框架本身不能解析识别),才需要重写这两个方法
		preProcessXml(root);
           //该方法开始真正解析BeanDefinition(详解见:第8讲)
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);

		this.delegate = parent;
	}
 
   内部代码块1:
   protected BeanDefinitionParserDelegate createDelegate(
			XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
            //创建一个BeanDefinitionParserDelegate 
		BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
           //执行初始化操作,就是设置一个默认值 (详情见:内部代码块2)
		delegate.initDefaults(root, parentDelegate);
		return delegate;
	}
 
 内部代码块2:
 /**
	 * Initialize the default lazy-init, autowire, dependency check settings,
	 * init-method, destroy-method and merge settings. Support nested 'beans'
	 * element use cases by falling back to the given parent in case the
	 * defaults are not explicitly set locally.
	 * @see #populateDefaults(DocumentDefaultsDefinition, DocumentDefaultsDefinition, org.w3c.dom.Element)
	 * @see #getDefaults()
	 */
	public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
             //(详情见:内部代码块3)
		populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
            //触发一个默认注册事件。
		this.readerContext.fireDefaultsRegistered(this.defaults);
	}
 
  内部代码块3:
  /**
	 * Populate the given DocumentDefaultsDefinition instance with the default lazy-init,
	 * autowire, dependency check settings, init-method, destroy-method and merge settings.
	 * Support nested 'beans' element use cases by falling back to <literal>parentDefaults</literal>
	 * in case the defaults are not explicitly set locally.
	 * @param defaults the defaults to populate
	 * @param parentDefaults the parent BeanDefinitionParserDelegate (if any) defaults to fall back to
	 * @param root the root element of the current bean definition document (or nested beans element)
	 */
   //这个方法就是把root中的属性设置到新创建的DocumentDefaultsDefinition 中
	protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
		String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
		if (DEFAULT_VALUE.equals(lazyInit)) {
			// Potentially inherited from outer <beans> sections, otherwise falling back to false.
			lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
		}
		defaults.setLazyInit(lazyInit);

		String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
		if (DEFAULT_VALUE.equals(merge)) {
			// Potentially inherited from outer <beans> sections, otherwise falling back to false.
			merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
		}
		defaults.setMerge(merge);

		String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
		if (DEFAULT_VALUE.equals(autowire)) {
			// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
			autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
		}
		defaults.setAutowire(autowire);

		// Don't fall back to parentDefaults for dependency-check as it's no longer supported in
		// <beans> as of 3.0. Therefore, no nested <beans> would ever need to fall back to it.
		defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));

		if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
			defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
		}
		else if (parentDefaults != null) {
			defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
		}

		if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
			defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
		}
		else if (parentDefaults != null) {
			defaults.setInitMethod(parentDefaults.getInitMethod());
		}

		if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
			defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
		}
		else if (parentDefaults != null) {
			defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
		}

		defaults.setSource(this.readerContext.extractSource(root));
	}    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值