spring源码解析bean定义五UtilNamespaceHandler

前言

这次介绍UtilNamespaceHandler

正文

找到这个方法

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

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);
      }
   }

找到这行代码

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));
   }

找到这行代码

//     获取解析命名空间的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#init

@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解析

//     handler解析
      return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

进入这个方法

扫描二维码关注公众号,回复: 441575 查看本文章
@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注入有几种类型

1、list

2、set

3、map

4、props

5、array

最后

本次介绍到这里,以上内容仅供参考。

扫码关注

进群讨论

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1810428