spring源码解析bean定义五ContextNamespaceHandler一

前言

本次介绍ContextNamespaceHandler的property-placeholder、property-override节点

正文

先找到解析bean定义的地方

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

进入这个方法

org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve这一行

初始化namespaceHandler类
            namespaceHandler.init();

进入这个方法

org.springframework.context.config.ContextNamespaceHandler#init

@Override
public void init() {
   registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
   registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
   registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
   registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
   registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
   registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
   registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
   registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}

返回到这个方法这一行

org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)

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

进入这个方法

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.AbstractSingleBeanDefinitionParser#parseInternal这一行代码

doParse(element, parserContext, builder);

进入这个方法

org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser#doParse

@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
   super.doParse(element, parserContext, builder);

   builder.addPropertyValue("ignoreUnresolvablePlaceholders",
         Boolean.valueOf(element.getAttribute("ignore-unresolvable")));

   String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
   if (StringUtils.hasLength(systemPropertiesModeName) &&
         !systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {
      builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_" + systemPropertiesModeName);
   }

   if (element.hasAttribute("value-separator")) {
      builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
   }
   if (element.hasAttribute("trim-values")) {
      builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
   }
   if (element.hasAttribute("null-value")) {
      builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
   }
}

第一行先调用了父类的方法

@Override
   protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
//    获取location属性
      String location = element.getAttribute("location");
      if (StringUtils.hasLength(location)) {
//       得到解析完占位符的路径
         location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location);
//       路径可以是多个,按照,分开
         String[] locations = StringUtils.commaDelimitedListToStringArray(location);
         builder.addPropertyValue("locations", locations);
      }

      String propertiesRef = element.getAttribute("properties-ref");
      if (StringUtils.hasLength(propertiesRef)) {
         builder.addPropertyReference("properties", propertiesRef);
      }

      String fileEncoding = element.getAttribute("file-encoding");
      if (StringUtils.hasLength(fileEncoding)) {
         builder.addPropertyValue("fileEncoding", fileEncoding);
      }

      String order = element.getAttribute("order");
      if (StringUtils.hasLength(order)) {
         builder.addPropertyValue("order", Integer.valueOf(order));
      }

      builder.addPropertyValue("ignoreResourceNotFound",
            Boolean.valueOf(element.getAttribute("ignore-resource-not-found")));

      builder.addPropertyValue("localOverride",
            Boolean.valueOf(element.getAttribute("local-override")));

      builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   }

返回到这个方法

org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)

protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
   doParse(element, builder);
}

找到子类实现

org.springframework.context.config.PropertyOverrideBeanDefinitionParser#doParse

@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
   super.doParse(element, parserContext, builder);

   builder.addPropertyValue("ignoreInvalidKeys",
         Boolean.valueOf(element.getAttribute("ignore-unresolvable")));

}

先调用了父类的方法

最后

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

扫码关注

进群讨论

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1810429
今日推荐