上一篇博客 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中进行处理的,都是在为他人做嫁衣。