热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring源码讲解之parseBeanDefinitionElement

parseBeanDefinitionElement方法是在org.springframework.beans.factory.xml.BeanDefinitionParserDe

parseBeanDefinitionElement 方法是在 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate 类中定义的,主要作用是解析 bean 元素并将其结果赋值给 org.springframework.beans.factory.config.BeanDefinitionHolder 实例进行存储。 该方法接收一个类型为 org.w3c.dom.Element 的参数,返回值类为 org.springframework.beans.factory.config.BeanDefinitionHolder。该方法会在org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element, BeanDefinitionParserDelegate) 方法中调用。


源码

@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {return parseBeanDefinitionElement(ele, null);
}

parseBeanDefinitionElement 方法的实现

@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, &#64;Nullable BeanDefinition containingBean) {// 获取 id 属性String id &#61; ele.getAttribute(ID_ATTRIBUTE);// 获取 name 属性String nameAttr &#61; ele.getAttribute(NAME_ATTRIBUTE);List<String> aliases &#61; new ArrayList<>();if (StringUtils.hasLength(nameAttr)) {// 解析 name 属性中的值String[] nameArr &#61; StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);aliases.addAll(Arrays.asList(nameArr));}String beanName &#61; id;if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {beanName &#61; aliases.remove(0);if (logger.isTraceEnabled()) {logger.trace("No XML &#39;id&#39; specified - using &#39;" &#43; beanName &#43;"&#39; as bean name and " &#43; aliases &#43; " as aliases");}}if (containingBean &#61;&#61; null) {// 检查 bean 名称和 bean 别名是否唯一checkNameUniqueness(beanName, aliases, ele);}// 重点方法// 解析 bean 元素到 BeanDefinition 中AbstractBeanDefinition beanDefinition &#61; parseBeanDefinitionElement(ele, beanName, containingBean);if (beanDefinition !&#61; null) {// 如果 beanName 为空&#xff0c;通过 beanDefinition 信息生成一个 beanNameif (!StringUtils.hasText(beanName)) {try {if (containingBean !&#61; null) {beanName &#61; BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);}else {beanName &#61; this.readerContext.generateBeanName(beanDefinition);// Register an alias for the plain bean class name, if still possible,// if the generator returned the class name plus a suffix.// This is expected for Spring 1.2/2.0 backwards compatibility.String beanClassName &#61; beanDefinition.getBeanClassName();if (beanClassName !&#61; null &&beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {aliases.add(beanClassName);}}if (logger.isTraceEnabled()) {logger.trace("Neither XML &#39;id&#39; nor &#39;name&#39; specified - " &#43;"using generated bean name [" &#43; beanName &#43; "]");}}catch (Exception ex) {error(ex.getMessage(), ele);return null;}}String[] aliasesArray &#61; StringUtils.toStringArray(aliases);return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);}return null;
}

parseBeanDefinitionElement 方法的实现

&#64;Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, &#64;Nullable BeanDefinition containingBean) {// 记录 bean 的解析状态this.parseState.push(new BeanEntry(beanName));String className &#61; null;if (ele.hasAttribute(CLASS_ATTRIBUTE)) {// 获取 calss 属性的值className &#61; ele.getAttribute(CLASS_ATTRIBUTE).trim();}String parent &#61; null;if (ele.hasAttribute(PARENT_ATTRIBUTE)) {// 获取 parent 属性的值parent &#61; ele.getAttribute(PARENT_ATTRIBUTE);}try {// 创建一个 AbstractBeanDefinition 实例// 默认类型是 org.springframework.beans.factory.support.GenericBeanDefinitionAbstractBeanDefinition bd &#61; createBeanDefinition(className, parent);// 解析 bean 定义相关的属性parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));// 解析 meta 子元素parseMetaElements(ele, bd);// 解析 lookup-method 子元素parseLookupOverrideSubElements(ele, bd.getMethodOverrides());// 解析 replaced-method 子元素parseReplacedMethodSubElements(ele, bd.getMethodOverrides());// 解析 constructor-arg 子元素parseConstructorArgElements(ele, bd);// 解析 property 子元素parsePropertyElements(ele, bd);// 解析 qualifier 子元素parseQualifierElements(ele, bd);bd.setResource(this.readerContext.getResource());bd.setSource(extractSource(ele));return bd;}catch (ClassNotFoundException ex) {error("Bean class [" &#43; className &#43; "] not found", ele, ex);}catch (NoClassDefFoundError err) {error("Class that bean class [" &#43; className &#43; "] depends on not found", ele, err);}catch (Throwable ex) {error("Unexpected failure during bean definition parsing", ele, ex);}finally {this.parseState.pop();}return null;
}

parseBeanDefinitionElement 方法讲解完毕&#xff0c;部分方法没有进行详细讲解&#xff08;例如&#xff1a;parseBeanDefinitionAttributes、parseMetaElements 等方法&#xff09;&#xff0c;此部分代码都在 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate 类中进行定义和实现&#xff0c;想了解的朋友可以去此类中进行查看。


推荐阅读
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • andr ... [详细]
author-avatar
金爽20111018
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有