Spring IOC 配置元数据的解析

概述

本文介绍配置元数据的解析,即由xml文档/java配置的元数据,如何由容器的实现类使用各种reader加载解析为BeanDefinition存储在容器中。

  • xml配置元数据的解析
  • java配置元数据的解析 TODO 未完成。

xml配置元数据的解析

前面介绍过,Spring IoC 容器的输入之一,配置元数据,它描述了我们要创建的beans的各种属性以及bean之间的依赖关系。Spring IoC容器要使用这些数据来实例化、配置、组装并管理我们需要的beans。

其中,一种流行在很久之前的一种基础的配置元数据便是xml,通常我们会创建一个xml配置文件,里面各种方式配置我们需要的bean的属性,如:

<bean id="helloWorld" class="**.**.HelloWorld">
    <property name="name" value="spring-ioc-test"/>
</bean>

其中 HellowWorld 是一个Java Pojo,有一个类型为字符串的属性name;然后我们会创建一个ApplicationContext,或者更基础的容器XmlBeanFactory,将这个xml文件路径传入构造器,即创建了一个容器,并可以从中获得我们在xml中配置的HellowWorld bean:

// 创建容器并从容器中获得bean
new ClassPathXmlApplicationContext("ioc/initialization/spring-hello-world.xml");
applicationContext.getBean("helloWorld", HelloWorld.class);

上一节我们看到的一系列BeanFactory相关的类,操作的最基础数据是BeanDefinition,容器ApplicationContext或XmlBeanFactory初始化的第一部操作即:将配置元数据xml被转换为BeanDefinition并交给BeanFactory。

而xml形式的配置元数据在转换为BeanDefinition过程中主要使用的类为BeanDefinitionReader,这里简要记录调用链中的几个主要的方法和它们的基本功能:

// 将创建好的beanFactory放入XmlBeanDefinitionReader构造器创建
reader = new XmlBeanDefinitionReader(beanFactory);
// 循环使用reader的loadBeanDefinitions方法加载String类型的配置文件位置
reader.loadBeanDefinitions(configLocation);
// 最终使用重载方法,中间将文件位置转换为了 EncodedResource
reader.loadBeanDefinitions(encodedResource);
// 经过对Resource的包装,进入doLoadBeanDefinitions方法
reader.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
// doLoadBeanDefinitions中调用两个方法,oLoadDocument,registerBeanDefinitions
reader.doLoadDocument(inputSource, resource);
reader.registerBeanDefinitions(doc, resource);
// 显然第一个用来将resource解析为Document
// 第二个使用解析的doc注册BeanDefinitions,我们进入registerBeanDefinitions
// 创建一个BeanDefinitionDocumentReader
documentReader = createBeanDefinitionDocumentReader();
// 这个reader来做实际的BeanDefinition解析操作
documentReader.rgisterBeanDefinitions(doc, createReaderContext(resource));
// 这个方法里创建代理,递归解析doc标签根节点,检查profile
doRegisterBeanDefinitions(doc.getDocumentElement());
// 使用上一个方法中的代理,解析每个根节点
parseBeanDefinitions(root, this.delegate);
// 遍历根节点的子节点,根据其命名空间类型,执行子节点解析
// 默认命名空间子节点,如bean,alias,import等
parseDefaultElement(ele, delegate);
// 自定义命名空间子节点,需要获取NamespaceHandler进行处理
delegate.parseCustomElement(ele);
// 进入默认bean子节点的解析
processBeanDefinition(ele, delegate);
// 将标签创建为BeanDefinition
delegate.parseBeanDefinitionElement(ele);
// 装饰
delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
// 将上面的BeanDefinition注册到Registry,即BeanFactory
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

以上即完成了从xml文件位置读取资源文件,解析document,解析为BeanDefinition,注册到BeanDefinitionRegistry(即BeanFactory)的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值