死磕Spring之IoC篇 - BeanDefinition 的解析阶段(XML 文件) (4)

解析 <bean /> 标签相关属性,构造出一个 GenericBeanDefinition 对象,调用 parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) 方法

如果不存在 beanName,则根据 Class 对象的名称生成一个

创建 BeanDefinitionHolder 对象,设置 beanName 名称和 aliases 别名集合,返回

6. parseBeanDefinitionElement 重载方法

parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) 方法,解析 <bean /> 成 GenericBeanDefinition 对象,方法如下:

@Nullable public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, @Nullable BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); // <1> 获取 `class` 和 `parent` 属性 String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } try { // <2> 构建一个 GenericBeanDefinition 对象 `bd` AbstractBeanDefinition bd = createBeanDefinition(className, parent); // <3> 解析 `<bean />` 的各种属性并赋值 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); // 提取 description bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); // <4> 解析 `<bean />` 的子标签,生成的对象设置到 `bd` 中 // <4.1> 解析 `<meta />` 元数据标签 parseMetaElements(ele, bd); // <4.2> 解析 `<lookup-method />` 标签 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // <4.3> 解析 `<replaced-method />` 标签 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // <4.4> 解析 `<constructor-arg />` 构造函数的参数集合标签 parseConstructorArgElements(ele, bd); // <4.5> 解析 `<property />` 属性标签 parsePropertyElements(ele, bd); // <4.5> 解析 `<qualifier />` 标签 parseQualifierElements(ele, bd); // <5> 设置 Bean 的 `resource` 资源为 XML 文件资源 bd.setResource(this.readerContext.getResource()); // <6> 设置 Bean 的 `source` 来源为 `<bean />` 标签对象 bd.setSource(extractSource(ele)); return bd; } // ... 省略 catch 各种异常 finally { this.parseState.pop(); } return null; }

过程如下:

获取 class 和 parent 属性

构建一个 GenericBeanDefinition 对象 bd,设置 parentName 和 beanClass(Class 对象)或者 className(Class 名称)

解析 <bean /> 的各种属性并赋值:scope、abstract、lazy-init、autowire、depends-on、autowire-candidate、primary、init-method、destroy-method、factory-method

解析 <bean /> 的子标签,生成的对象设置到 bd 中

解析 <meta /> 元数据标签,将 key-value 保存至 Map 中

解析 <lookup-method /> 标签,解析成 LookupOverride 对象,用于实现 Bean 中的某个方法

解析 <replaced-method /> 标签,解析成 ReplaceOverride 对象,用于替换 Bean 中的某个方法

解析 <constructor-arg /> 构造函数的参数集合标签,将各个参数解析出来,可根据 index 属性进行排序

解析 <property /> 属性标签,将各个属性解析出来,每个属性对应一个 PropertyValue,添加至 bd 的 MutablePropertyValues 属性中

解析 <qualifier /> 标签,解析出需要注入的对象 AutowireCandidateQualifier

设置 Bean 的 resource 资源为 XML 文件资源

设置 Bean 的 source 来源为 <bean /> 标签对象

lookup-method,会被解析成 LookupOverride 对象,replaced-method 会被解析成 ReplaceOverride 对象,这两个标签不是很常用

lookup-method:例如一个在一个抽象类中定义了抽象方法,可以通过这个标签定义一个 Bean 实现这个方法,Spring 会动态改变抽象类该方法的实现

replace-method:通过这个标签定义一个 Bean,去覆盖对应的方法,Spring 会动态替换类的这个方法

BeanDefinitionReaderUtils

org.springframework.beans.factory.support.BeanDefinitionReaderUtils,BeanDefinition 的解析过程中的工具类

7. registerBeanDefinition 方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygpww.html