前言java
本文转自“天河聊技术”微信公众号node
此次介绍UtilNamespaceHandlerspring
正文微信
找到这个方法app
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitionsdom
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 根节点是不是命名空间 http://www.springframework.org/schema/beans 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)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
找到这行代码ide
else { delegate.parseCustomElement(ele); }
@Nullable public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); }
@Nullable public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } // 获取解析命名空间的handler NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } // handler解析 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
找到这行代码post
// 获取解析命名空间的handler NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
@Override @Nullable public NamespaceHandler resolve(String namespaceUri) { // 获取handlerMappings,从META-INF/spring.handlers这个路径加载 Map<String, Object> handlerMappings = getHandlerMappings(); Object handlerOrClassName = handlerMappings.get(namespaceUri); if (handlerOrClassName == null) { return null; } else if (handlerOrClassName instanceof NamespaceHandler) { return (NamespaceHandler) handlerOrClassName; } else { String className = (String) handlerOrClassName; try { Class<?> handlerClass = ClassUtils.forName(className, this.classLoader); // handler必须是这个类型 NamespaceHandler if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri + "] does not implement the [" + NamespaceHandler.class.getName() + "] interface"); } // 建立namespaceHandler类 NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); // 初始化namespaceHandler类 namespaceHandler.init(); handlerMappings.put(namespaceUri, namespaceHandler); return namespaceHandler; } catch (ClassNotFoundException ex) { throw new FatalBeanException("Could not find NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", ex); } catch (LinkageError err) { throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", err); } } }
进入这个方法org.springframework.beans.factory.xml.UtilNamespaceHandler#initui
@Override public void init() { registerBeanDefinitionParser("constant", new ConstantBeanDefinitionParser()); registerBeanDefinitionParser("property-path", new PropertyPathBeanDefinitionParser()); registerBeanDefinitionParser("list", new ListBeanDefinitionParser()); registerBeanDefinitionParser("set", new SetBeanDefinitionParser()); registerBeanDefinitionParser("map", new MapBeanDefinitionParser()); registerBeanDefinitionParser("properties", new PropertiesBeanDefinitionParser()); }
返回到这个方法org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)这一行代码进行handler解析this
// handler解析 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
进入这个方法
@Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { // 得到bean定义解析器 BeanDefinitionParser parser = findParserForElement(element, parserContext); return (parser != null ? parser.parse(element, parserContext) : null); }
进入这个方法
org.springframework.beans.factory.xml.NamespaceHandlerSupport#parse
@Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { // 得到bean定义解析器 BeanDefinitionParser parser = findParserForElement(element, parserContext); return (parser != null ? parser.parse(element, parserContext) : null); }
进入这个方法
org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parse
@Override @Nullable public final BeanDefinition parse(Element element, ParserContext parserContext) { // 解析bean定义的模板方法 AbstractBeanDefinition definition = parseInternal(element, parserContext); if (definition != null && !parserContext.isNested()) { try { // 解析id属性 String id = resolveId(element, definition, parserContext); if (!StringUtils.hasText(id)) { parserContext.getReaderContext().error( "Id is required for element '" + parserContext.getDelegate().getLocalName(element) + "' when used as a top-level tag", element); } String[] aliases = null; if (shouldParseNameAsAliases()) { // 解析name属性 String name = element.getAttribute(NAME_ATTRIBUTE); if (StringUtils.hasLength(name)) { aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name)); } } BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases); registerBeanDefinition(holder, parserContext.getRegistry()); if (shouldFireEvents()) { BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder); postProcessComponentDefinition(componentDefinition); parserContext.registerComponent(componentDefinition); } } catch (BeanDefinitionStoreException ex) { String msg = ex.getMessage(); parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element); return null; } } return definition; }
找到这一行代码
// 解析bean定义的模板方法 AbstractBeanDefinition definition = parseInternal(element, parserContext);
@Override protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); String parentName = getParentName(element); if (parentName != null) { } builder.getRawBeanDefinition().setParentName(parentName); Class<?> beanClass = getBeanClass(element); if (beanClass != null) { builder.getRawBeanDefinition().setBeanClass(beanClass); } else { String beanClassName = getBeanClassName(element); if (beanClassName != null) { builder.getRawBeanDefinition().setBeanClassName(beanClassName); } } builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); // 获取内部bean的bean定义 BeanDefinition containingBd = parserContext.getContainingBeanDefinition(); // 若是匿名bean有scope,外部bean的scope以这个为主 if (containingBd != null) { // Inner bean definition must receive same scope as containing bean. builder.setScope(containingBd.getScope()); } // 是否延迟加载 if (parserContext.isDefaultLazyInit()) { // Default-lazy-init applies to custom bean definitions as well. builder.setLazyInit(true); } doParse(element, parserContext, builder); return builder.getBeanDefinition(); }
进入这个方法
// 调用此方法时会具体调用子类重写的方法,如org.springframework.beans.factory.xml.UtilNamespaceHandler.ListBeanDefinitionParser.doParse() protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { doParse(element, builder); }
找到上面的实现方法
org.springframework.beans.factory.xml.UtilNamespaceHandler.ListBeanDefinitionParser#doParse list节点解析
@Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { List<Object> parsedList = parserContext.getDelegate().parseListElement(element, builder.getRawBeanDefinition()); builder.addPropertyValue("sourceList", parsedList); String listClass = element.getAttribute("list-class"); if (StringUtils.hasText(listClass)) { builder.addPropertyValue("targetListClass", listClass); } // 获取scope属性值 String scope = element.getAttribute(SCOPE_ATTRIBUTE); if (StringUtils.hasLength(scope)) { builder.setScope(scope); } } }
public List<Object> parseListElement(Element collectionEle, @Nullable BeanDefinition bd) { // value-type标签 String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = collectionEle.getChildNodes(); ManagedList<Object> target = new ManagedList<>(nl.getLength()); target.setSource(extractSource(collectionEle)); target.setElementTypeName(defaultElementType); target.setMergeEnabled(parseMergeAttribute(collectionEle)); parseCollectionElements(nl, target, bd, defaultElementType); return target; }
public boolean parseMergeAttribute(Element collectionElement) { // merge属性 String value = collectionElement.getAttribute(MERGE_ATTRIBUTE); // 若是是default则以beans的配置为主 if (DEFAULT_VALUE.equals(value)) { value = this.defaults.getMerge(); } return TRUE_VALUE.equals(value); }
protected void parseCollectionElements( NodeList elementNodes, Collection<Object> target, @Nullable BeanDefinition bd, String defaultElementType) { for (int i = 0; i < elementNodes.getLength(); i++) { Node node = elementNodes.item(i); // description 解析属性 if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)) { // 递归调用 target.add(parsePropertySubElement((Element) node, bd, defaultElementType)); } } }
进入这个方法
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parsePropertySubElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition, java.lang.String)
@Nullable public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd, @Nullable String defaultValueType) { // 若是不是beans节点 if (!isDefaultNamespace(ele)) { return parseNestedCustomElement(ele, bd); } // 解析bean节点 else if (nodeNameEquals(ele, BEAN_ELEMENT)) { // 解析<bean>节点的bean定义 BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd); if (nestedBd != null) { // 解析内部的required的元素 nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd); } return nestedBd; } // ref属性指定的节点 else if (nodeNameEquals(ele, REF_ELEMENT)) { // A generic reference to any name of any bean. // 获取bean属性值 String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE); boolean toParent = false; if (!StringUtils.hasLength(refName)) { // A reference to the id of another bean in a parent context.parent属性值获取另外一个bean的引用 refName = ele.getAttribute(PARENT_REF_ATTRIBUTE); toParent = true; if (!StringUtils.hasLength(refName)) { error("'bean' or 'parent' is required for <ref> element", ele); return null; } } if (!StringUtils.hasText(refName)) { error("<ref> element contains empty target attribute", ele); return null; } RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent); ref.setSource(extractSource(ele)); return ref; } // 解析idref属性,注入的是bean的id而不是bean的实例 else if (nodeNameEquals(ele, IDREF_ELEMENT)) { return parseIdRefElement(ele); } // 若是是value节点 else if (nodeNameEquals(ele, VALUE_ELEMENT)) { return parseValueElement(ele, defaultValueType); } // 若是是null节点 else if (nodeNameEquals(ele, NULL_ELEMENT)) { // It's a distinguished null value. Let's wrap it in a TypedStringValue // object in order to preserve the source location. TypedStringValue nullHolder = new TypedStringValue(null); nullHolder.setSource(extractSource(ele)); return nullHolder; } // 若是是array节点 else if (nodeNameEquals(ele, ARRAY_ELEMENT)) { return parseArrayElement(ele, bd); } // 若是是list节点 else if (nodeNameEquals(ele, LIST_ELEMENT)) { return parseListElement(ele, bd); } // 若是是set节点 else if (nodeNameEquals(ele, SET_ELEMENT)) { return parseSetElement(ele, bd); } // 若是是map节点 else if (nodeNameEquals(ele, MAP_ELEMENT)) { return parseMapElement(ele, bd); } // 若是是props节点 else if (nodeNameEquals(ele, PROPS_ELEMENT)) { return parsePropsElement(ele); } else { error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele); return null; } }
找到这行代码
// 解析idref属性,注入的是bean的id而不是bean的实例 else if (nodeNameEquals(ele, IDREF_ELEMENT)) { return parseIdRefElement(ele); }
@Nullable public Object parseIdRefElement(Element ele) { // A generic reference to any name of any bean.获取bean属性值 String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE); if (!StringUtils.hasLength(refName)) { error("'bean' is required for <idref> element", ele); return null; } if (!StringUtils.hasText(refName)) { error("<idref> element contains empty target attribute", ele); return null; } RuntimeBeanNameReference ref = new RuntimeBeanNameReference(refName); ref.setSource(extractSource(ele)); return ref; }
找到这行代码
// 若是是value节点 else if (nodeNameEquals(ele, VALUE_ELEMENT)) { return parseValueElement(ele, defaultValueType); }
public Object parseValueElement(Element ele, @Nullable String defaultTypeName) { // It's a literal value. String value = DomUtils.getTextValue(ele); // 获取type属性值 String specifiedTypeName = ele.getAttribute(TYPE_ATTRIBUTE); String typeName = specifiedTypeName; if (!StringUtils.hasText(typeName)) { typeName = defaultTypeName; } try { TypedStringValue typedValue = buildTypedStringValue(value, typeName); typedValue.setSource(extractSource(ele)); typedValue.setSpecifiedTypeName(specifiedTypeName); return typedValue; } catch (ClassNotFoundException ex) { error("Type class [" + typeName + "] not found for <value> element", ele, ex); return value; } }
找到这行代码
// 若是是array节点 else if (nodeNameEquals(ele, ARRAY_ELEMENT)) { return parseArrayElement(ele, bd); }
public Object parseArrayElement(Element arrayEle, @Nullable BeanDefinition bd) { // 获取value-type属性值 String elementType = arrayEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = arrayEle.getChildNodes(); ManagedArray target = new ManagedArray(elementType, nl.getLength()); target.setSource(extractSource(arrayEle)); target.setElementTypeName(elementType); target.setMergeEnabled(parseMergeAttribute(arrayEle)); parseCollectionElements(nl, target, bd, elementType); return target; }
public boolean parseMergeAttribute(Element collectionElement) { // merge属性 String value = collectionElement.getAttribute(MERGE_ATTRIBUTE); // 若是是default则以beans的配置为主 if (DEFAULT_VALUE.equals(value)) { value = this.defaults.getMerge(); } return TRUE_VALUE.equals(value); }
protected void parseCollectionElements( NodeList elementNodes, Collection<Object> target, @Nullable BeanDefinition bd, String defaultElementType) { for (int i = 0; i < elementNodes.getLength(); i++) { Node node = elementNodes.item(i); // description 解析属性 if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)) { // 递归调用 target.add(parsePropertySubElement((Element) node, bd, defaultElementType)); } } }
找到这行代码
// 若是是list节点 else if (nodeNameEquals(ele, LIST_ELEMENT)) { return parseListElement(ele, bd); }
public List<Object> parseListElement(Element collectionEle, @Nullable BeanDefinition bd) { // value-type标签 String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = collectionEle.getChildNodes(); ManagedList<Object> target = new ManagedList<>(nl.getLength()); target.setSource(extractSource(collectionEle)); target.setElementTypeName(defaultElementType); target.setMergeEnabled(parseMergeAttribute(collectionEle)); parseCollectionElements(nl, target, bd, defaultElementType); return target; }
找到这行代码
// 若是是set节点 else if (nodeNameEquals(ele, SET_ELEMENT)) { return parseSetElement(ele, bd); }
public Set<Object> parseSetElement(Element collectionEle, @Nullable BeanDefinition bd) { // 获取value-type属性值 String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE); NodeList nl = collectionEle.getChildNodes(); ManagedSet<Object> target = new ManagedSet<>(nl.getLength()); target.setSource(extractSource(collectionEle)); target.setElementTypeName(defaultElementType); target.setMergeEnabled(parseMergeAttribute(collectionEle)); parseCollectionElements(nl, target, bd, defaultElementType); return target; }
找到这行代码
// 若是是map节点 else if (nodeNameEquals(ele, MAP_ELEMENT)) { return parseMapElement(ele, bd); }
public Map<Object, Object> parseMapElement(Element mapEle, @Nullable BeanDefinition bd) { // 获取key-type属性值 String defaultKeyType = mapEle.getAttribute(KEY_TYPE_ATTRIBUTE); // 获取value-type属性值 String defaultValueType = mapEle.getAttribute(VALUE_TYPE_ATTRIBUTE); // 获取entry节点的子节点 List<Element> entryEles = DomUtils.getChildElementsByTagName(mapEle, ENTRY_ELEMENT); ManagedMap<Object, Object> map = new ManagedMap<>(entryEles.size()); map.setSource(extractSource(mapEle)); map.setKeyTypeName(defaultKeyType); map.setValueTypeName(defaultValueType); map.setMergeEnabled(parseMergeAttribute(mapEle)); for (Element entryEle : entryEles) { // Should only have one value child element: ref, value, list, etc. // Optionally, there might be a key child element. NodeList entrySubNodes = entryEle.getChildNodes(); Element keyEle = null; Element valueEle = null; for (int j = 0; j < entrySubNodes.getLength(); j++) { Node node = entrySubNodes.item(j); if (node instanceof Element) { Element candidateEle = (Element) node; // 若是是key节点 if (nodeNameEquals(candidateEle, KEY_ELEMENT)) { if (keyEle != null) { error("<entry> element is only allowed to contain one <key> sub-element", entryEle); } else { keyEle = candidateEle; } } else { // Child element is what we're looking for.若是是description节点 if (nodeNameEquals(candidateEle, DESCRIPTION_ELEMENT)) { // the element is a <description> -> ignore it } else if (valueEle != null) { error("<entry> element must not contain more than one value sub-element", entryEle); } else { valueEle = candidateEle; } } } } // Extract key from attribute or sub-element. Object key = null; // 是否有key属性 boolean hasKeyAttribute = entryEle.hasAttribute(KEY_ATTRIBUTE); // 是否有key-ref属性 boolean hasKeyRefAttribute = entryEle.hasAttribute(KEY_REF_ATTRIBUTE); if ((hasKeyAttribute && hasKeyRefAttribute) || (hasKeyAttribute || hasKeyRefAttribute) && keyEle != null) { error("<entry> element is only allowed to contain either " + "a 'key' attribute OR a 'key-ref' attribute OR a <key> sub-element", entryEle); } if (hasKeyAttribute) { key = buildTypedStringValueForMap(entryEle.getAttribute(KEY_ATTRIBUTE), defaultKeyType, entryEle); } else if (hasKeyRefAttribute) { String refName = entryEle.getAttribute(KEY_REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error("<entry> element contains empty 'key-ref' attribute", entryEle); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(extractSource(entryEle)); key = ref; } else if (keyEle != null) { key = parseKeyElement(keyEle, bd, defaultKeyType); } else { error("<entry> element must specify a key", entryEle); } // Extract value from attribute or sub-element. Object value = null; // 是否有value属性 boolean hasValueAttribute = entryEle.hasAttribute(VALUE_ATTRIBUTE); // 是否有value-ref属性 boolean hasValueRefAttribute = entryEle.hasAttribute(VALUE_REF_ATTRIBUTE); // 是否有value-type属性 boolean hasValueTypeAttribute = entryEle.hasAttribute(VALUE_TYPE_ATTRIBUTE); if ((hasValueAttribute && hasValueRefAttribute) || (hasValueAttribute || hasValueRefAttribute) && valueEle != null) { error("<entry> element is only allowed to contain either " + "'value' attribute OR 'value-ref' attribute OR <value> sub-element", entryEle); } if ((hasValueTypeAttribute && hasValueRefAttribute) || (hasValueTypeAttribute && !hasValueAttribute) || (hasValueTypeAttribute && valueEle != null)) { error("<entry> element is only allowed to contain a 'value-type' " + "attribute when it has a 'value' attribute", entryEle); } if (hasValueAttribute) { String valueType = entryEle.getAttribute(VALUE_TYPE_ATTRIBUTE); if (!StringUtils.hasText(valueType)) { valueType = defaultValueType; } value = buildTypedStringValueForMap(entryEle.getAttribute(VALUE_ATTRIBUTE), valueType, entryEle); } else if (hasValueRefAttribute) { String refName = entryEle.getAttribute(VALUE_REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error("<entry> element contains empty 'value-ref' attribute", entryEle); } RuntimeBeanReference ref = new RuntimeBeanReference(refName); ref.setSource(extractSource(entryEle)); value = ref; } else if (valueEle != null) { // 递归调用 value = parsePropertySubElement(valueEle, bd, defaultValueType); } else { error("<entry> element must specify a value", entryEle); } // Add final key and value to the Map. map.put(key, value); } return map; }
找到这行代码
// 若是是props节点 else if (nodeNameEquals(ele, PROPS_ELEMENT)) { return parsePropsElement(ele); }
public Properties parsePropsElement(Element propsEle) { ManagedProperties props = new ManagedProperties(); props.setSource(extractSource(propsEle)); props.setMergeEnabled(parseMergeAttribute(propsEle)); // 获取prop的子节点 List<Element> propEles = DomUtils.getChildElementsByTagName(propsEle, PROP_ELEMENT); for (Element propEle : propEles) { // 获取key属性值 String key = propEle.getAttribute(KEY_ATTRIBUTE); // Trim the text value to avoid unwanted whitespace // caused by typical XML formatting. String value = DomUtils.getTextValue(propEle).trim(); TypedStringValue keyHolder = new TypedStringValue(key); keyHolder.setSource(extractSource(propEle)); TypedStringValue valueHolder = new TypedStringValue(value); valueHolder.setSource(extractSource(propEle)); props.put(keyHolder, valueHolder); } return props; }
返回到这个方法
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
@Nullable public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } // 获取解析命名空间的handler NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } // handler解析 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
以上是util的namespace的源码解析。
总结一下
util注入有几种类型
一、list
二、set
三、map
四、props
五、array
最后
本次介绍到这里,以上内容仅供参考。