spring源碼解析bean定義五UtilNamespaceHandler

前言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

 

最後

本次介紹到這裏,以上內容僅供參考。

相關文章
相關標籤/搜索