Spring解析XML配置文件----BeanDefinition---Meta读取

Spring解析XML文件,其实就是构造一个 BeanDefinition 对象的过程。

BeanDefinition 是一个接口,它描述了一个 Bean 实例,实例中的参数,即配置文件中的属性。

它继承 AttributeAccessor BeanMetadataElement 接口。两个接口定义如下:

  • AttributeAccessor :定义了与其它对象的(元数据)进行连接和访问的约定,即对属性的修改,包括获取、设置、删除。
  • BeanMetadataElement:Bean 元对象持有的配置元素可以通过getSource() 方法来获取。

Spring解析XML配置文件----BeanDefinition---Meta读取_第1张图片

        由图可知,我们常用的三个实现类有:ChildBeanDefinition、GenericBeanDefinition、RootBeanDefinition,三者都继承 AbstractBeanDefinition。如果配置文件中定义了父  和 子  ,则父  用 RootBeanDefinition表示,子  用 ChildBeanDefinition 表示,而没有父  的就使用RootBeanDefinition 表示。GenericBeanDefinition 为一站式服务类。AbstractBeanDefinition对三个子类共同的类信息进行抽象。

 

 

解析Bean:

在BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法中,完成解析。

Spring解析XML配置文件----BeanDefinition---Meta读取_第2张图片

进入createBeanDefinition方法中可知,它创建了一个GenericBeanDefinition对象返回给AbstractBeanDefinition

Spring解析XML配置文件----BeanDefinition---Meta读取_第3张图片

接下来如方法名所示,依次调用方法,解析XML标签,并为AbstractBeanDefinition实例赋值:

setDescription:description元素;

parseMetaElements:Meta元素;

parseLookupOverrideSubElements:lookup-method元素;

parseReplacedMethodSubElements:replace-method元素;

parseConstructorArgElements:constructor-arg元素;

parsePropertyElements:property元素;

parseQualifierElements:qualify元素;

 

学习时,因为配置了Meta元素但是不会读取,因此特为Meta元素说明。

 

        在parseMetaElements,可以看出,从Meta标签读取key和value后,将之存入了BeanMetadataAttribute对象,并最终通过addMetadataAttribute方法存入attributeAccessor对象中。

        BeanMetadataAttributeAccessor类是AbstractBeanDefinition接口的父类。

Spring解析XML配置文件----BeanDefinition---Meta读取_第4张图片

      所以我们如果想读取Meta元素的内容,需要从attributeAccessor对象中读取;看看attributeAccessor在哪里?

Spring解析XML配置文件----BeanDefinition---Meta读取_第5张图片

        该方法被parseBeanDefinitionElement调用,在该方法的最后,new了一个BeanDefinitionHolder对象;然后把值存在了beanDefinition中。

Spring解析XML配置文件----BeanDefinition---Meta读取_第6张图片

返回了的BeanDefinitionHolder去了哪里?

Spring解析XML配置文件----BeanDefinition---Meta读取_第7张图片

        方法先被parseBeanDefinitionElement调用,而parseBeanDefinitionElement方法又被DefaultBeanDefinitionDocumentReader类中的processBeanDefinition方法调用。

BeanDefinitionReaderUtils.registerBeanDefinition中,有一个registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法,用来注册BeanDefinition。

Spring解析XML配置文件----BeanDefinition---Meta读取_第8张图片

         Spring的最基本接口就是BeanFactory,而BeanFactory最常用的实现类就是DefaultListableBeanFactory,不难想象,BeanDefinition一定是在这个类中,存在了Spring容器里。结果也的确是。

        BeanDefinitionMap便是Spring存放Bean的容器。

至此,BeanDefinition便存储好了。当想读取Meta元素时,要先获取BeanDefinition实例。

 

Spring解析XML配置文件----BeanDefinition---Meta读取_第9张图片

        这里只能使用DefaultListableBeanFactory,因为其他的Spring容器需要new一个DefaultListableBeanFactory,而这样,BeanDefinitionMap是空的,会导致查不出来数据。

        getBeanDefinition会根据String从BeanDefinitionMap中查询一个BeanDefinition实例,从这个实例中,getAttribute即可获取Meta元素的value值。

输出结果:

 

 

 

 

 

你可能感兴趣的:(WEB)