解析自定义标签一
默认标签的解析过程:
DefaultBeanDefinitionDocumentReader 的 processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)
方法,负责 bean
标签的解析:
- 在解析过程中,首先调用
BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele)
方法,完成默认标签的解析。
- 如果解析成功(返回的
bdHolder != null
),则调用 BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder)
方法,完成自定义标签元素的解析。
decorateBeanDefinitionIfRequired()
方法
该方法处理自定义标签的解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) { return decorateBeanDefinitionIfRequired(ele, originalDef, null); }
public BeanDefinitionHolder decorateBeanDefinitionIfRequired( Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = originalDef;
NamedNodeMap attributes = ele.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Node node = attributes.item(i); finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); }
NodeList children = ele.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { finalDefinition = decorateIfRequired(node, finalDefinition, containingBd); } } return finalDefinition; }
|
<1>
和 <2>
处,都是遍历,前者遍历的是属性( attributes
),后者遍历的是子节点( childNodes
),最终调用的都是 #decorateIfRequired(Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd)
方法,装饰对应的节点( Node )。
decorateIfRequired()
方法
在decorateBeanDefinitionIfRequired()
方法中分别遍历了属性
和子节点
后,都会执行该方法进行对应节点(Node)的装饰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public BeanDefinitionHolder decorateIfRequired( Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(node); if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) { NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler != null) { BeanDefinitionHolder decorated = handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd)); if (decorated != null) { return decorated; } } else if (namespaceUri.startsWith("http://www.springframework.org/schema/")) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node); } else { if (logger.isDebugEnabled()) { logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]"); } } } return originalDef; }
|