spring源碼解析bean定義五ContextNamespaceHandler一

前言node

本文轉自「天河聊技術」微信公衆號spring

本次介紹ContextNamespaceHandler的property-placeholder、property-override節點微信

 

正文dom

先找到解析bean定義的地方ide

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

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

找到這行代碼this

//     獲取解析命名空間的handler
      NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);

進入這個方法spa

org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve這一行component

初始化namespaceHandler類
            namespaceHandler.init();

進入這個方法server

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

}

先調用了父類的方法

 

最後

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

相關文章
相關標籤/搜索