分享

Spring是如何解析xml配置的

 liang1234_ 2019-01-20
 Spring方法路径:org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element, String, BeanDefinition)
一、创建用于属性承载的BeanDefinition
BeanDefinition在Spring中有三个实现,RootBeanDefinition,ChildBeanDefinition,和GenericBeanDefinition
父<bean>用rootBeanDefinition,子<bean>用Child承载,GenericBeanDefinition是2.5版本后新增的文件配置属性定义类,是一站式服务类
二、解析各种属性,将配置中的bean属性设置到bd中,源码如下:
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
                  BeanDefinition containingBean, AbstractBeanDefinition bd) {
            if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
                  error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
            }
            else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
                  bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
            }
            else if (containingBean != null) {
                  // Take default from containing bean in case of an inner bean definition.
                  bd.setScope(containingBean.getScope());
            }
            if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
                  bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
            }
            String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(lazyInit)) {
                  lazyInit = this.defaults.getLazyInit();
            }
            bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
            String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
            bd.setAutowireMode(getAutowireMode(autowire));
            if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
                  String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
                  bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
            }
            String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
            if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
                  String candidatePattern = this.defaults.getAutowireCandidates();
                  if (candidatePattern != null) {
                        String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
                        bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
                  }
            }
            else {
                  bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
            }
            if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
                  bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
            }
            if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
                  String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
                  if (!"".equals(initMethodName)) {
                        bd.setInitMethodName(initMethodName);
                  }
            }
            else {
                  if (this.defaults.getInitMethod() != null) {
                        bd.setInitMethodName(this.defaults.getInitMethod());
                        bd.setEnforceInitMethod(false);
                  }
            }
            if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
                  String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
                  bd.setDestroyMethodName(destroyMethodName);
            }
            else {
                  if (this.defaults.getDestroyMethod() != null) {
                        bd.setDestroyMethodName(this.defaults.getDestroyMethod());
                        bd.setEnforceDestroyMethod(false);
                  }
            }
            if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
                  bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
            }
            if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
                  bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
            }
            return bd;
      }
三、解析子元素meta属性
四、解析子元素lookup_method属性(获取器注入的配置:Spring特殊的一种方法注入,它是把一个方法声明为返回某种类型的bean,但实际要返回的bean是在配置文件里面配置的,此方法可用在设计有些可热插拔的功能上,解除程序依赖。)
五、解析子元素的replaced_method
六、解析子元素的constructor-arg,源码解析:
遍历所有的节点,也就是提取所有的constructor-arg,然后进行解析。
首先提取constructor-arg上所有的必要的属性(index、type、name)
如果配置了index:
(1)解析constructor-arg的子元素。
(2)使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
(3)将type、name、index属性一并封装在ConstructorArgumentValues中并添加到当前BeanDefinition的constructorArgumentValues的IndexedArgumentValue中
如果未配置index:
(1)解析constructor-arg的子元素。
(2)使用ConstructorArgumentValues.ValueHolder类型来封装解析出来的元素
(3)将type、name、index属性一并封装在ConstructorArgumentValues中并添加到当前BeanDefinition的constructorArgumentValues的GenericArgumentValue

对构造函数中元素的解析,经历了以下过程:
  1. 略过了description或者meta
  2. 提取constructor-arg上的ref和value属性,以便于根据规则验证正确性,其规则为在constructor-arg上不存在以下情况:同时既有ref属性,又有value属性;存在ref或者value属性且又有子元素
  3. ref属性的处理。使用RuntimeBeanReference封装对应的ref名称
  4. value属性的处理,使用TypedStringValue封装
  5. 子元素的处理,构造函数中又嵌入了子元素map
七、解析配置的property属性,并将内容封装在BeanDefinition中的propertyValue属性中
八、解析Qualifier属性。

代码经过以上步骤,就完成了xml配置文件到GenericBeanDefinition的转换,xml中的所有配置,都可以在GenericBeanDefinition中找到配置

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多