Spring源码学习--Spring配置文件解析BeanDefinitionDocumentReader(三)

上一篇博客 Spring源码学习--xml配置解析文件BeanDefinitionReader(二)中我们已经了解到BeanDefinitionReader已经将Spring的xml配置文件解析成Document对象了,接下来的解析处理工作是在BeanDefinitionDocumentReader中对Document对象进行解析工作了。

BeanDefinitionDocumentReader接口及其实现类:


BeanDefinitionDocumentReader提供的方法:

public interface BeanDefinitionDocumentReader {

	void registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
			throws BeanDefinitionStoreException;

}
BeanDefinitionDocumentReader的实现类DefaultBeanDefinitionDocumentReader定义了对一些xml配置文件基本的元素的解析处理操作


在这里我们可能会有一个疑问,在Spring的xml配置文件中经常看到的aop等相关的配置是在什么地方解析处理的,其实他们都是通过NamespaceHandler实现类来完成的,接下来我们会对其进行详细的介绍。

在DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法中开始对Document进行解析。

	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		doRegisterBeanDefinitions(root);
	}

在doRegisterBeanDefinitions中会创建BeanDefinitionParserDelegate来对Document进行解析

protected void doRegisterBeanDefinitions(Element root) {
		
		BeanDefinitionParserDelegate parent = this.delegate;
		//创建BeanDefinitionParserDelegate,真正xml中各种元素的解析
		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;
				}
			}
		}

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

		this.delegate = parent;
	}
在parseBeanDefinitions会对Node进行判断,如果是上面配置默认解析的spring标签,则会在DefaultBeanDefinitionDocumentReader中进行解析,否则的话就需要 BeanDefinitionParserDelegate来委派找到解析处理器。

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)) {
						//默认的一些标签在DefaultBeanDefinitionDocumentReader进行解析
						parseDefaultElement(ele, delegate);
					}
					else {
						//如果不是默认的就需要在通过委派模式来寻找解析处理器
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			//如果不是默认的就需要在通过委派模式来寻找解析处理器
			delegate.parseCustomElement(root);
		}
	}
在parseDefaultElement中会对一些默认的标签import,alias,bean,beans标签进行处理

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		//解析import标签
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		//解析alias标签
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		//解析bean标签
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		//解析beans标签,就是进行递归解析
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}

对bean标签解析,最终还是在BeanDefinitionParserDelegate中对元素进行处理解析生成BeanDefinitionHolder,其实bean元素的解析的结果是一个BeanDefinition对象,其包含了所有的bean的属性设置,processBeanDefinition中的BeanDefinitionReaderUtils的处理结果是将BeanDefinition注册到BeanFactory中。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//最终还是在BeanDefinitionParserDelegate中进行元素解析
		//BeanDefinitionHolder是对BeanDefinition的封装,包括BeanDefinition,beanName,aliases
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				//处理的操作是将bean的元数据BeanDifinition注册到BeanFactory中
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
总结:BeanDefinitionDocumentReader中也没有对xml中的bean元素进行处理操作,其真正的处理操作是在BeanDefinitionParserDelegate中进行处理的,都是在为他人做嫁衣。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值