BeanDefinition

这里写目录标题

      • BeanDefinition
      • BeanDefinitionReader
        • AbstractBeanDefinitionReader
        • XmlBeanDefinitionReader

BeanDefinition

上述Spring的基本运行中,你所有的定义描述信息都在XML文件里面,如何读取呢?
当然通过 new ClassPathXmlApplicationContext("applicationcontext.xml")
该代码就是读取XML文件,而Bean对象信息就在xml里面,Bean的定义信息通过XML读取到了IOC容器中,此时,IOC的容器出现了bean的定义信息,并赋予了一个名字:BeanDefinition

BeanDefinitionReader

BeanDefinitionReader :规范信息的接口
BeanDefinitionReader 的作用是读取 Spring 配置文件中的内容,将其转换为 IoC 容器内部的数据结构:BeanDefinition

  • BeanDefinitionRegistry 接口一次只能注册一个 BeanDefinition
  • 只能自己构造 BeanDefinition 类来注册
  • BeanDefinitionReader 解决了这些问题
    • BeanDefinitionReader 可以使用一个 BeanDefinitionRegistry 构造
    • 然后通过 loadBeanDefinitions()等方法,把 Resources 转化为多个 BeanDefinition 并注册到 BeanDefinitionRegistry
public interface BeanDefinitionReader {//返回Bean工厂以向其注册Bean定义。BeanDefinitionRegistry getRegistry();/**返回资源加载器以用于资源位置。可以检查ResourcePatternResolver接口并进行相应的转换,以针对给定的资源模式加载多个资源。一个null返回值表明,绝对资源加载不适用于这个bean定义阅读器。这主要用于从bean定义资源中导入其他资源,例如,通过XML bean定义中的“ import”标记。但是,建议相对于定义资源应用此类导入;只有明确的完整资源位置才会触发绝对资源加载。**/@NullableResourceLoader getResourceLoader();//返回用于Bean类的类加载器。@NullableClassLoader getBeanClassLoader();//返回BeanNameGenerator用于匿名Bean(未指定显式Bean名称)。BeanNameGenerator getBeanNameGenerator();//从指定的资源加载bean定义。int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException;int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException;//从指定的资源位置加载bean定义。//该位置也可以是位置模式,前提是此bean定义读取器的ResourceLoader是ResourcePatternResolver。int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException;int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException;
}

关于 BeanDefinitionReader 的结构图如下:

BeanDefinitionReader
AbstractBeanDefinitionReader
XmlBeanDefinitionReader
PropertiesBeanDefinitionReader
GroovyBeanDefinitionReader
AbstractBeanDefinitionReader

该类是实现了 BeanDefinitionReader 和 EnvironmentCapable 接口的抽象类,提供常见属性:

  • 工作的 bean 工厂、
  • 资源加载器、
  • 用于加载 bean 类的类加载器、
  • 环境等

在这里插入图片描述
子类如下:

  • XmlBeanDefinitionReader:读取 XML 文件定义的 BeanDefinition
  • PropertiesBeanDefinitionReader:可以从属性文件,Resource,Property 对象等读取 BeanDefinition
  • GroovyBeanDefinitionReader:可以读取 Groovy 语言定义的 Bean

关于该类最核心的方法是 loadBeanDefinitions()方法,所以接下来我们主要就是分析该方法
在这里插入图片描述
在这里插入图片描述
根据资源加载器的不同,来处理资源路径,从而返回多个或一个资源,然后再将资源作为参数传递给 loadBeanDefinitions(resources)方法。在该类中存在一个 loadBeanDefinitions(Resource… resources)方法,该方法用于处理多个资源,归根结底,最后还是调用 loadBeanDefinitions((Resource)resource)方法,该方法的具体实现在 XmlBeanDefinitionReader 中。

XmlBeanDefinitionReader

该类作为 AbstractBeanDefinitionReader 的扩展类,继承了 AbstractBeanDefinitionReader 所有的方法,同时也扩展了很多新的方法,主要用于读取 XML 文件中定义的 bean。
XmlBeanDefinitionReader ,将xml中定义的bean解析为BeanDefinition对像

xml配置如下:

 <bean id=? class=?><property name=? value=?><property name=? ref=?></bean><bean id=? class=?><constructor-arg name=? value=?><constructor-arg name=? ref=?></bean>

具体使用如下:

public void getBeanDefinition(){ClassPathResource resource = new ClassPathResource("application_context.xml");DefaultListableBeanFactory factory = new DefaultListableBeanFactory();XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);reader.loadBeanDefinitions(resource);
}

获取资源

  • 获取 BeanFactory
    • 根据新建的 BeanFactory 创建一个BeanDefinitionReader对象,该Reader 对象为资源的解析器

装载资源

  • 整个过程就分为三个步骤:
    • 资源定位
      • 我们一般用外部资源来定义 Bean 对象,所以在初始化 IoC 容器的第一步就是需要定位这个外部资源
    • 装载
      • 装载就是
        • BeanDefinition 的载入
        • BeanDefinitionReader 读取
        • 解析 Resource 资源
        • 也就是将用户定义的 Bean 表示成 IoC 容器 的内部数据结构:BeanDefinition\
        • 在 IoC 容器内部维护着一个 BeanDefinition Map 的数据结构,在配置文件中每一个都对应着一个 BeanDefinition 对象。
    • 注册
      • 向 IoC 容器注册在上一步解析好的 BeanDefinition,这个过程是通过 BeanDefinitionRegistry 接口来实现的
      • 本质上是将解析得到的 BeanDefinition 注入到一个 HashMap 容器中,IoC 容器就是通过这个HashMap 来维护这些 BeanDefinition 的
      • 注意:此过程并没有完成依赖注入,依赖注册是发生在应用第一次调用 getBean()向容器索要 Bean 时。当然我们可以通过设置预处理,即对某个 Bean 设置 lazyInit 属性

接着上述的 loadBeanDefinitions(),我们看一下在 XmlBeanDefinitionReader 类中的具体实现
在这里插入图片描述
loadBeanDefinitions(resource) 是加载资源的真正实现,

加载BeanDefinition
封装
ResourcesCurrentlyBeingLoaded.get
已经存在该资源
没有存在
指定的 XML文件
Resource
EncodedResource
获取已经加载过的资源
抛出BeanDefinitionStoreException异常
将encodedResource加入其中
从 encodedResource 获取封装的Resource资源并从 Resource 中获取相应的 InputStream
最后将 InputStream 封装为 InputSource 调用 doLoadBeanDefinitions方法

loadBeanDefinitions(resource) 是加载资源的真正实现
从指定的 XML 文件加载 Bean Definition,这里会对 Resource 封装成 EncodedResource,主要是为了对 Resource 进行编码,保证内容读取的正确性。封装成 EncodedResource 后,调用 loadBeanDefinitions(encodedResource)。

  1. 首先通过 resourcesCurrentlyBeingLoaded.get() 来获取已经加载过的资源,
  2. 然后将 encodedResource
  3. 如果 resourcesCurrentlyBeingLoaded 中已经存在该资源,则抛出 BeanDefinitionStoreException
  4. 完成后从 encodedResource 获取封装的 Resource 资源并从 Resource 中获取相应的 InputStream
  5. 最后将 InputStream 封装为 InputSource 调用 doLoadBeanDefinitions()

方法 doLoadBeanDefinitions() 为从 xml 文件中加载 Bean Definition 的真正逻辑

demo测试

  1. 实体类
package com.example.spring_01.entity;import lombok.Data;@Data
public class Person {private String name;private String  age;
}
  1. xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.example.spring_01.entity.Person"><property name="name" value="sb"/><property name="age" value="666"/></bean>
</beans>
  1. 测试demo
 @Testpublic void demoTest() {//创建一个spring容器DefaultListableBeanFactory factory = new DefaultListableBeanFactory();//定义一个xml方式的bean的读取器,需要传入一个bean的注册器XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);//根据xml文件的位置解析定义的bean,并将其注册到我们上面指定的spring容器中String location="bean.xml";xmlBeanDefinitionReader.loadBeanDefinitions(location);for (String beanName:factory.getBeanDefinitionNames()){System.out.println(beanName+"===>"+factory.getBean(beanName));}}
  1. 结果集
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/785518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见微服务的组件?

注册中心&#xff1a;就是一个服务注册的地方&#xff0c;我们可以把拆分的服务注册到注册中心&#xff0c;这样注册中心就能管理这些服务&#xff0c;服务之间的调用就会很方便&#xff0c;通过服务名就能相互调用。 负载均衡&#xff1a;被调用放的负载均衡&#xff0c;比如…

【智能算法】黄金正弦算法(GSA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2017年&#xff0c;Tanyildizi等人受到正弦函数单位圆内扫描启发&#xff0c;提出了黄金正弦算法&#xff08;Golden Sine Algorithm, GSA&#xff09;。 2.算法原理 2.1算法思想 GSA来源于正弦函…

FreeBSD下路由问题留档

碰到了一个非常神奇的事情&#xff0c;一台笔记本有以太网和wifi&#xff0c;都可以连到同一台路由器&#xff0c;ip地址配置在同一网段&#xff0c;但是如果插上网线&#xff0c;再拔掉网线的话&#xff0c;那么wifi即使连上&#xff0c;也无法上网。 看路由信息&#xff0c;发…

【Spring源码分析】透过源码看透Spring事务

阅读此需阅读下面这些博客先【Spring源码分析】Bean的元数据和一些Spring的工具【Spring源码分析】BeanFactory系列接口解读【Spring源码分析】执行流程之非懒加载单例Bean的实例化逻辑【Spring源码分析】从源码角度去熟悉依赖注入&#xff08;一&#xff09;【Spring源码分析】…

书生浦语笔记一

2023年6月&#xff0c;InternLM的第一代大模型正式发布。仅一个月后&#xff0c;该模型以及其全套工具链被开源。随后&#xff0c;在8月份&#xff0c;多模态语料库chat7B和lagent也被开源。而在接下来的9月份&#xff0c;InternLM20B的开源发布进一步加强了全线工具链的更新。…

所有企业都在用的微服务框架,需要多强的服务集成能力?

在数字化时代&#xff0c;随着业务规模的扩大和系统复杂性的增加&#xff0c;传统的单体应用架构由于其固有的局限性&#xff0c;已无法高效支撑企业日益增长的业务需求。 为了突破这一瓶颈&#xff0c;微服务架构以其独特的优势崭露头角&#xff0c;逐渐成为企业数字化转型的…

腾讯云容器与Serverless的融合:探索《2023技术实践精选集》中的创新实践

腾讯云容器与Serverless的融合&#xff1a;探索《2023技术实践精选集》中的创新实践 文章目录 腾讯云容器与Serverless的融合&#xff1a;探索《2023技术实践精选集》中的创新实践引言《2023腾讯云容器和函数计算技术实践精选集》整体评价特色亮点分析Serverless与Kubernetes的…

【刷题】 二分查找入门

送给大家一句话: 总有一天&#xff0c;你会站在最亮的地方&#xff0c;活成自己曾经渴望的模样—— 苑子文 & 苑子豪《我们都一样 年轻又彷徨》 二分查找入门 1 前言2 Leetcode 704. 二分查找2.1 题目描述2.2 算法思路 3 Leetcode 34. 在排序数组中查找元素的第一个和最后…

学习笔记——C语言基本概念指针(下)——(8)

1.指针和数组 数组指针 -- 指向数组的指针。 指针数组 -- 数组的元素都是指针。 换句话理解就是&#xff1a;数组指针就是个指针&#xff0c;指针数组就是个数组。 1.1数组指针 数组指针&#xff1a;指向数组的指针&#xff1b; 先回顾一下数组的特点&#xff1a; 1.相…

【C语言】联合体、枚举: 联合体与结构体区别,枚举的优点

目录 1、联合体 1.1、什么是联合体 1.2、联合体的声明 1.3、联合体的特点 1.4、联合体与结构体区别 1.5、联合体的大小 2、枚举 2.1、枚举类型的声明 2.2、枚举类型的优点 3、三种自定义类型&#xff1a;结构体、联合体、枚举 正文 1、联合体 1.1、什么是联合体 联…

如何使用route-detect在Web应用程序路由中扫描身份认证和授权漏洞

关于route-detect route-detect是一款功能强大的Web应用程序路由安全扫描工具&#xff0c;该工具可以帮助广大研究人员在Web应用程序路由中轻松识别和检测身份认证漏洞和授权漏洞。 Web应用程序HTTP路由中的身份认证&#xff08;authn&#xff09;和授权&#xff08;authz&…

题目:小明的背包5(蓝桥OJ 1178)

问题描述&#xff1a; 解题思路&#xff1a; 分组背包模板题&#xff0c;与优化01背包的不同之处在于第一维不可省略&#xff0c;要写s循环。注意要初始化 #include <bits/stdc.h> using namespace std; const int N 1e3 9; int dp[N][N]; // 分组背包模板&#xff0c;…

代码随想录阅读笔记-二叉树【平衡二叉树】

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 返回 true 。 示例 2: 给定二叉树 [1,2,…

ZKFair 创新之旅,新阶段如何塑造财富前景

在当前区块链技术的发展中&#xff0c;Layer 2&#xff08;L2&#xff09;解决方案已成为提高区块链扩容性、降低交易成本和提升交易速度的关键技术&#xff0c;但它仍面临一些关键问题和挑战&#xff0c;例如用户体验的改进、跨链互操作性、安全性以及去中心化程度。在这些背景…

Unity中UI系统1——GUI

介绍 工作原理和主要作用 基本控件 a.文本和按钮控件 练习&#xff1a; b.多选框和单选框 练习&#xff1a; 用的是第三种方法 c.输入框和拖动框 练习&#xff1a; 练习二&#xff1a; e.图片绘制和框 练习&#xff1a; 复合控件 a.工具栏和选择网格 练习&#xff1a; b.滚动视…

纷享销客如何向生态型CRM进化 创始人罗旭给出了答案

自己挣1块钱时&#xff0c;渠道合作伙伴能够挣1块甚至更多。这是纷享销客与生态共建之道。 2024年纷享销客北方战区渠道生态伙伴发展共建会于日前在北京举行。在这场主题为“聚力纷享共赢巅峰”的大会上&#xff0c;各方探讨了企业高质量增长之源与SaaS行业渠道发展之路&#…

云渲染实用工具:3ds max怎么改低版本?

3ds Max是建模领域广泛采用的专业软件&#xff0c;它通过定期更新来不断增强功能和提升性能。但这些频繁的更新有时会导致一些插件暂时无法与新版本完全兼容。为了解决这个问题&#xff0c;设计师们可以采用一个简单有效的方法&#xff0c;那就是将较新版本的3ds Max文件进行版…

基于Unity+Vue3通信交互的WebGL项目发布实践

基于UnityVue3通信交互的WebGL项目发布实践 实践路线 基于UnityVue3通信交互的WebGL项目发布实践问题背景准备工作解决方案项目实践小目标搭建Unity测试项目 创建Vue3测试项目运行项目验证unity和vue通信功能总结与展望 问题背景 我们最近需要把unity开发的pc项目迁移到web端&…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.9-3.11

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第三周&#xff1a;浅层神经网络(Shallow neural networks)3.9 神 经 网 络 的 梯 度 下 降 &#xff08; Gradient descent for neural networks&#xff09;3.10&#xff08;选修&#xff0…

C#让标题栏闪烁着动起来的方法

目录 1.API函数FlashWindow &#xff08;1&#xff09;添加命名空间 &#xff08;2&#xff09;声明DllImport方法 &#xff08;3&#xff09;FlashWindow函数 2.P/Invoke 3.再来一个示例 在Windows系统中&#xff0c;当程序在后台运行时&#xff0c;如果某个窗体的提示信…