spring bean解析过程分析

近期想扩展定义自己的配置文件的标签,采用以前写的而一个篇扩展的方式,只能扩展自己的附加的类,无法实现组装bean的方式,所以针对spring对默认的命名空间的解析bean的方式进行分析

 

主要的分析代码都在DefaultBeanDefinitionDocumentReader中的方法registerBeanDefinitions中

  this.readerContext = readerContext;

  logger.debug("Loading bean definitions");
  Element root = doc.getDocumentElement();

  BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);

  preProcessXml(root);
  parseBeanDefinitions(root, delegate);
  postProcessXml(root);

 

其实preProcessXml(root)和postProcessXml(root)供去扩展,默认没有实现任何功能

主要是parseBeanDefinitions(root, delegate);
  if (delegate.isDefaultNamespace(root.getNamespaceURI())) {            //TODO:core bean处理
   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;
     String namespaceUri = ele.getNamespaceURI();
     if (delegate.isDefaultNamespace(namespaceUri)) {
      parseDefaultElement(ele, delegate);
     }
     else {
      delegate.parseCustomElement(ele);                      //TODO:解析bean
     }
    }
   }
  }
  else {
   delegate.parseCustomElement(root);                         //自定义元素
  }

 

如果是默认的命名空间采用parseDefaultElement(ele, delegate)去处理,如果是自定义的delegate.parseCustomElement(ele)去处理

首先查看 default的解析,default包含如下几个标签,分别解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
  if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT)) {
   importBeanDefinitionResource(ele);
  }
  else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT)) {
   processAliasRegistration(ele);
  }
  else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT)) {   //TODO:处理xml中定义的bean元素
   processBeanDefinition(ele, delegate);
  }

 }

我们主要关注的是bean的解析,所以只是查看一下processBeanDefinition(ele, delegate);
  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
  if (bdHolder != null) {
   bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
   try {
    // Register the final decorated instance.
    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
   }
   catch (BeanDefinitionStoreException ex) {
    getReaderContext().error("Failed to register bean definition with name '" +
      bdHolder.getBeanName() + "'",  ele, ex);
   }
   // Send registration event.
   getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
  }

解析完成,组装成BeanComponentDefinition

 

 自定义标签的解析方式

  String namespaceUri = ele.getNamespaceURI();
  NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
  if (handler == null) {
   error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
   return null;
  }
  return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
通过方法查看出来,如果是自定义的标签,就读取在spring.handler中配置的Handler进行配置的解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值