Spring是如何解析xml配置的

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中找到配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值