完成了默认标签的接信息之后,返回来再看processBeanDefinition方法,除了默认的标签之外,还有自定义标签
DefaultBeanDefinitionDocumentReader.java中processBeanDefinition方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
由之前的分析可知,parseBeanDefinitionElement是对默认的标签进行解析,decorateBeanDefinitionIfRequired(ele,bdholder);则是对自定义的标签进行解析:
< bean id=”test” class=”test.MyClass”>
当Spring中的bean使用的是默认的标签配置,但是其子元素使用了自定义的配置,那么就会执行decorateBeanDefinitionIfRequired方法,
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
return this.decorateBeanDefinitionIfRequired(ele, definitionHolder, (BeanDefinition)null);
}
decorateBeanDefinitionIfRequired方法的第三个参数设置为空,这个参数是父类bean,当对某个嵌套配置进行分析时,这里需要传递父类beanDefinition,分析源码得知这里传递的参数是为了使用父类的scope属性,以备若子类没有设置scope时默认使用父类的属性,首先调用时时顶层配置,所以传递为空:
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = definitionHolder;
NamedNodeMap attributes = ele.getAttributes();
//遍历所有的属性,查看是否有适用于修饰的子元素
for(int i = 0; i < attributes.getLength(); ++i) {
Node node = attributes.item(i);
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
NodeList children = ele.getChildNodes();
//遍历所有的子节点,是否有适用于修饰的子元素
for(int i = 0; i < children.getLength(); ++i) {
Node node = children.item(i);
if (node.getNodeType() == 1) {
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
由decorateBeanDefinitionIfRequired方法可知,当该方法遍历到元素属性或者子节点有自定义属性时,调用decorateIfRequired方法
public BeanDefinitionHolder decorateIfRequired(Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
//获取自定义标签的命名空间
String namespaceUri = this.getNamespaceURI(node);
//对非默认标签进行修饰
if (!this.isDefaultNamespace(namespaceUri)) {
//根据命名标签找到对应的处理器,进行修饰
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
return handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
}
if (namespaceUri != null && namespaceUri.startsWith("http://www.springframework.org/")) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
}
}
return originalDef;
}
上述方法,首先是获取属性或者元素的命名空间,来判断该元素或者该属性是否适用于自定义标签的解析条件,找出来自定义类型所对应的NamespaceHandler进行进一步的解析,在该方法中对于默认的标签处理是直接略过的,因为默认的标签到这步已经被处理完了,这里只处理bean的自定义标签和属性进行处理。