《Spring Framework实战》8:4.1.3.Bean 概述
欢迎观看《Spring Framework实战》视频教程
Spring IoC 容器管理一个或多个 bean。这些 bean 是使用 您提供给容器的配置元数据(例如,以 XML <bean/>定义的形式)。
在容器本身中,这些 bean 定义表示为BeanDefinition对象,其中包含(除其他信息外)以下元数据:
- 包限定的类名:通常是 bean 被定义。
- Bean 行为配置元素,这些元素表示 Bean 在 容器(范围、生命周期回调等)。
- 对 Bean 执行其工作所需的其他 Bean 的引用。这些 引用也称为协作者或依赖项。
- 要在新创建的对象中设置的其他配置设置 — 例如,大小 pool 的限制或要在管理 连接池。
此元数据转换为构成每个 Bean 定义的一组属性。 下表描述了这些属性:
表 1.bean 定义 | |
属性 | 解释 |
Class | 实例化 Bean |
Name | 命名 Bean |
Scope | Bean 作用域 |
Constructor arguments | 依赖关系注入 |
Properties | 依赖关系注入 |
Autowiring mode | 自动装配协作者 |
Lazy initialization mode | 延迟初始化的 Bean |
Initialization method | 初始化回调 |
Destruction method | 销毁回调 |
除了包含有关如何创建特定 bean,则实现还允许注册现有的 在容器外部创建的对象(由用户创建)。这是通过访问 ApplicationContext 的 实现。 支持 此注册通过 和 方法。但是,典型的应用程序仅使用通过常规定义的 bean Bean 定义元数据。ApplicationContextBeanFactorygetBeanFactory()DefaultListableBeanFactoryDefaultListableBeanFactoryregisterSingleton(..)registerBeanDefinition(..)
Bean 元数据和手动提供的单例实例需要注册为 early 为了让容器在自动装配期间正确地推断它们 和其他内省步骤。在覆盖现有元数据和现有 在某种程度上支持单例实例,在 运行时(与工厂的实时访问同时)不受官方支持,可能会 导致并发访问异常、Bean 容器中的状态不一致,或两者兼而有之。 |
-
-
-
- 覆盖 Bean
-
-
当使用已经 分配。虽然 bean 覆盖是可能的,但它会使配置更难阅读。
Bean 覆盖将在将来的发行版中弃用。 |
要完全禁用 bean 覆盖,可以在刷新之前将标志设置为 on。在这样的设置中, 如果使用 Bean 覆盖,则引发 Exception。allowBeanDefinitionOverridingfalseApplicationContext
默认情况下,容器会记录每次在级别覆盖 Bean 的尝试,以便 您可以相应地调整您的配置。虽然不建议这样做,但您可以静音 通过将标志设置为 .INFOallowBeanDefinitionOverridingtrue
Java 配置
如果使用 Java Configuration,则相应的方法始终以静默方式覆盖 具有相同组件名称的扫描 Bean 类,只要该方法的返回类型与该 Bean 类匹配即可。这只是意味着容器将调用 Factory 方法优先使用 Bean 类上任何预先声明的构造函数。@Bean@Bean@Bean
我们承认在测试场景中覆盖 bean 很方便,并且 从 Spring Framework 6.2 开始明确支持这一点。有关更多详细信息,请参阅此部分。 |
-
-
-
- 命名 Bean
-
-
每个 bean 都有一个或多个标识符。这些标识符在 托管 Bean 的容器。一个 bean 通常只有一个标识符。但是,如果它 需要多个,额外的可以被视为别名。
在基于 XML 的配置元数据中,您可以使用 attribute、 attribute 或 两者都用于指定 Bean 标识符。该属性允许您指定一个 。 通常,这些名称是字母数字('myBean'、'someService' 等),但它们 也可以包含特殊字符。如果要为 bean,你也可以在属性中指定它们,用逗号 () 分隔, 分号 () 或空格。尽管该属性被定义为类型,但 Bean 唯一性是由容器强制执行的,而不是由 XML 强制执行的 解析 器。idnameididname,;idxsd:stringid
您不需要为 bean 提供 a 或 an。如果未显式提供 or,则容器将为该 bean 生成唯一名称。然而 如果要按名称引用该 bean,请使用元素或 Service Locator 样式查找,您必须提供名称。 不提供名称的动机与使用内部 bean 和自动装配协作者有关。nameidnameidref
Bean 命名约定
约定是在以下情况下对实例字段名称使用标准 Java 约定 命名 bean。也就是说,Bean 名称以小写字母开头,并且是驼峰式大小写的 从那里开始。此类名称的示例包括 、 等。accountManageraccountServiceuserDaologinController
一致地命名 bean 使您的配置更易于阅读和理解。 此外,如果你使用 Spring AOP,那么在将 advice 应用于一组 bean 时,它会有很大帮助 按名称相关。
通过在 Classpath 中进行组件扫描, Spring 会为 unnamed 生成 bean 名称 组件,遵循前面描述的规则:本质上,采用简单的类名 并将其初始字符转换为小写。然而,在(不寻常的)特别 当有多个字符并且同时具有第一个和第二个字符时 为大写,则保留原始大小写。这些规则与 定义者(Spring 在此处使用)。java.beans.Introspector.decapitalize |
在 Bean 定义之外为 Bean 设置别名
在 bean 定义本身中,您可以通过使用 属性指定的最多一个名称与任意数量的其他名称的组合 names 在属性中。这些名称可以是同一 bean 的等效别名 ,并且在某些情况下很有用,例如让应用程序中的每个组件 使用特定于该组件的 Bean 名称来引用公共依赖项 本身。idname
指定实际定义 bean 的所有别名并不总是足够的, 然而。有时需要为定义的 bean 引入别名 别处。在配置拆分的大型系统中,通常会出现这种情况 在每个子系统中,每个子系统都有自己的一组对象定义。 在基于 XML 的配置元数据中,您可以使用 Element 来完成 这。以下示例显示了如何执行此操作:<alias/>
<alias name="fromName" alias="toName"/>
在这种情况下,名为 使用此别名定义后,称为 。fromNametoName
例如,子系统 A 的配置元数据可以通过 的名称。子系统 B 的配置元数据可以引用 名称为 .编写主应用程序时 使用这两个子系统,则主应用程序通过 的名称。要让所有三个名称都引用同一个对象,您可以 将以下别名定义添加到配置元数据中:subsystemA-dataSourcesubsystemB-dataSourcemyApp-dataSource
<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>
现在每个组件和主应用程序都可以通过名称来引用 dataSource 这是唯一的,并且保证不会与任何其他定义冲突(有效地 创建命名空间),但它们引用同一个 bean。
Java 配置
如果使用 Java 配置,则注释可用于提供别名。 有关详细信息,请参阅使用 @Bean 注释。@Bean
-
-
-
- 实例化 Bean
-
-
bean定义本质上是创建一个或多个对象的配方。当被询问时,容器会查看命名bean的配方,并使用该bean定义封装的配置元数据来创建(或获取)实际对象。
如果使用基于XML的配置元数据,则需要在<bean/>元素的class属性中指定要实例化的对象的类型(或类)。这个类属性(在内部是BeanDefinition实例上的class属性)通常是必需的。(有关例外情况,请参阅使用实例工厂方法和Bean定义继承进行实例化。)您可以通过以下两种方式之一使用Class属性:
- 通常,在容器 它本身通过反射性地调用其构造函数来直接创建 Bean 等效于带有运算符的 Java 代码。
- 要指定包含static工厂方法的实际类,即 invoked 来创建对象,在不太常见的情况下,容器在类上调用static工厂方法来创建 Bean。返回的对象类型 从static工厂方法的调用可以是同一个类,也可以是另一个类 类。
嵌套类名
如果要为嵌套类配置 bean 定义,可以使用 binary name 或嵌套类的源名称。
例如,如果您在包中有一个名为 class 的 set,并且 此类有一个名为 的嵌套类,它们可以是 用美元符号 () 或点 () 分隔。因此,在 Bean 定义将是 或 。SomeThingcom.exampleSomeThingstaticOtherThing$.classcom.example.SomeThing$OtherThingcom.example.SomeThing.OtherThing
-
-
-
-
- 使用 Constructor 进行实例化
-
-
-
当你通过构造函数方法创建一个 bean 时,所有普通类都可以被 和 与 Spring 兼容。也就是说,正在开发的类不需要实现 任何特定接口或以特定方式编码。只需指定 bean 类应该就足够了。但是,具体取决于您为该特定 bean,则可能需要一个默认的(空的)构造函数。
Spring IoC 容器几乎可以管理您希望它管理的任何类。是的 不限于管理真正的 JavaBeans。大多数 Spring 用户更喜欢带有 仅对默认 (无参数) 构造函数和适当的 setter 和 getter 进行建模 在容器中的属性之后。你也可以有更多异国情调的非 bean 样式 类。例如,如果您需要使用遗留连接池 绝对不遵守 JavaBean 规范,Spring 可以将其管理为 井。
使用基于 XML 的配置元数据,您可以按如下方式指定 Bean 类:
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
有关向构造函数提供参数的机制的详细信息(如果需要) 以及在构造对象后设置对象实例属性,请参阅注入依赖项。
对于构造函数参数,容器可以选择相应的 constructor 在多个重载构造函数中。也就是说,为避免歧义, 建议使构造函数签名尽可能简单明了。 |
-
-
-
-
- 使用 Static Factory Method 进行实例化
-
-
-
定义使用静态工厂方法创建的 Bean 时,使用该属性指定包含该工厂方法的类和一个属性 named 来指定工厂方法本身的名称。您应该 能够调用此方法(使用可选参数,如下所述)并返回一个实时的 object,该对象随后被视为通过构造函数创建的。 这种 bean 定义的一个用途是在遗留代码中调用工厂。classstaticfactory-methodstatic
以下 Bean 定义指定将通过调用 Factory 方法。定义没有指定返回对象的类型(类), 而是包含 Factory 方法的类。在此示例中,method 必须是 method。以下示例说明如何 指定 Factory 方法:createInstance()static
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>
下面的示例展示了一个将与前面的 bean 定义一起使用的类:
Java
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
有关向工厂方法提供(可选)参数的机制的详细信息 以及在从工厂返回对象后设置对象实例属性, 详见 依赖关系和配置。
在工厂方法参数的情况下,容器可以选择相应的 method 的 method。也就是说,为避免歧义, 建议使工厂方法签名尽可能简单明了。 |
工厂方法重载的一个典型问题情况是 Mockito,它有许多 方法的重载。选择最具体的 可能 变体:mockmock <bean id="clientService" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg type="java.lang.Class" value="examples.ClientService"/> <constructor-arg type="java.lang.String" value="clientService"/> </bean> |
-
-
-
-
- 使用实例工厂方法进行实例化
-
-
-
与通过 static factory method 进行实例化类似,使用实例工厂方法进行实例化会调用非 static 方法创建一个新的 bean。要使用此功能 机制中,将属性留空,并在属性 在当前 (或 parent) 容器中指定 bean 的名称,其中包含 要调用以创建对象的 instance 方法。设置 factory 方法本身具有 attribute。以下示例显示了 如何配置这样的 bean:classfactory-beanfactory-method
<!-- the factory bean, which contains a method called createClientServiceInstance() --><bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean --></bean>
<!-- the bean to be created via the factory bean --><bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
以下示例显示了相应的类:
Java
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
一个工厂类还可以包含多个工厂方法,如下例所示:
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean --></bean>
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
以下示例显示了相应的类:
Java
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
private static AccountService accountService = new AccountServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
public AccountService createAccountServiceInstance() {
return accountService;
}
}
这种方法表明,工厂 Bean 本身可以通过 依赖注入 (DI)。 详见 依赖关系和配置。
在 Spring 文档中,“工厂 Bean”是指在 Spring 容器,它通过实例或静态工厂方法创建对象。相比之下,(注意大写)指的是特定于 Spring 的 FactoryBean 实现类。FactoryBean |
-
-
-
-
- 确定 Bean 的运行时类型
-
-
-
确定特定 bean 的运行时类型并非易事。中指定的类 Bean 元数据定义只是一个初始类引用,可能会组合在一起 替换为声明的工厂方法,或者是一个可能导致 bean 的运行时类型不同,或者在实例级别的情况下根本不设置 Factory 方法(通过指定名称解析)。 此外,AOP 代理可以使用基于接口的代理包装 bean 实例,其中 目标 Bean 的实际类型(仅其实现的接口)的有限公开。FactoryBeanfactory-bean
了解特定 Bean 的实际运行时类型的推荐方法是 对指定 Bean 名称的调用。这需要以上所有 cases 中,并返回调用的对象类型 将返回相同的 bean 名称。BeanFactory.getTypeBeanFactory.getBean
相关文章:

《Spring Framework实战》8:4.1.3.Bean 概述
欢迎观看《Spring Framework实战》视频教程 Spring IoC 容器管理一个或多个 bean。这些 bean 是使用 您提供给容器的配置元数据(例如,以 XML <bean/>定义的形式)。 在容器本身中,这些 bean 定义表示为BeanDefinition对象&a…...

BGP的local_preference本地优先级属性
一、BGP的local preference属性简介 1、local preference公认任意属性 当一条BGP路由器中存在多条去往同一目标网络的BGP路由时,BGP协议会对这些BGP路由属性进行比较,从而筛选出最佳到达目标网络的通达路径。本地优先属性,只在IBGP对等体之间…...

IP地址与端口号
ip地址与端口号 IP地址和端口号是网络通信中的两个重要概念,它们共同构成了网络通信的基础。 IP地址:网络世界的门牌号 定义:IP地址(Internet Protocol Address)是分配给网络设备的数字标签,用于在计算机网…...
Fastapi + vue3 自动化测试平台(2)--日志中间件
FastAPI Vue3 自动化测试平台(2)-- 日志中间件 前言 在开发和运行自动化测试平台时,日志功能是至关重要的一部分。日志不仅能帮助我们快速定位和解决问题,还能作为平台运行的记录依据,为后续分析和优化提供参考。 …...
iOS - AutoreleasePool
1. 基本数据结构 // AutoreleasePool 的基本结构 struct AutoreleasePoolPage {static pthread_key_t const key AUTORELEASE_POOL_KEY;magic_t const magic;id *next; // 指向下一个可存放对象的地址pthread_t const thread; // 所属线程AutoreleasePoolPage …...

1.CSS的复合选择器
1.1 什么是复合选择器 在CSS中,可以根据选择器的类型把选择器分为基础选择器和复合选择器,复合选择器是建立在基础选择器之上,对基础选择器进行组合形成的。 复合选择器可以更精准、更高效的选择目标元素(标签) 复…...

优质内容在个人IP运营中的重要性:以开源AI智能名片商城小程序为应用实例的深度探讨
摘要:在数字化时代,个人品牌(IP)的塑造与传播已成为各行各业提升影响力、吸引用户关注、促进商业转化的关键策略。优质内容作为连接个人IP与目标受众的桥梁,其在个人IP运营中的重要性不言而喻。本文旨在深入探讨优质内…...

Kafka性能测试
kafka是一个大数据消息队列(可以看做为缓存软件) 功能测试:能够读写数据 性能测试:1、测试生产者每秒往kafka写入的最大吞吐量 2、测试消费者每秒从kafka里获取消息最大吞吐量 硬件 3台物理机组成的kafka集群。 内存121G、24…...
解决Docker冲突问题
错误:docker-ce-cli conflicts with 2:docker-1.13.1-210.git7d71120.el7.centos.x86_64 错误:docker-ce conflicts with 2:docker-1.13.1-210.git7d71120.el7.centos.x86_64 您可以尝试添加 --skip-broken 选项来解决该问题 您可以尝试执行:…...
新手入门 React .tsx 项目:从零到实战
🚀 新手入门 React .tsx 项目:从零到实战 💻✨ 如果你是 React 新手,刚接触 .tsx 文件,不要担心!跟着这份指南,一步一步来,你很快就能上手了!👇 Ὅ…...

基于可信数据空间的企业数据要素与流通体系建设(附ppt 下载)
近期,可信数据空间会议召开。大数据系统软件国家工程研究中心总工程师王晨发表了题为《基于可信数据空间的企业数据要素与流通体系建设》主旨演讲。 篇幅限制,部分内容如下:...
二维数组:求最大元素及其所在的行坐标及列坐标(PTA)C语言
求出NM整型数组的最大元素及其所在的行坐标及列坐标(如果最大元素不唯一,选择位置在最前面的一个)。 函数接口定义: int fun(int array[N][M]) ; 注意:函数只需靠return返回最大元素的值, 行、列坐标通过…...

WebRtc01: 课程导学、框架介绍
应用 难点 课程大纲 学习收获 涉及内容 概述 用途 学习收获...

HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构
HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构 效果图DRAWPIEHQChart代码地址后台数据对接说明示例数据数据结构说明效果图 DRAWPIE DRAWPIE是hqchart插件独有的绘制饼图函数,可以通过麦语法脚本来绘制一个简单的饼图数据。 饼图显示的位置固定在右上角。 下…...
【cuda学习日记】2.2 使用2维网络(grid)和2维块(block)对矩阵进行求和
在2.0中进行了用一维网格和块对一维向量进行了求和。 在2.1中例化了二维的网格和块。 接下来进行2维网络(grid)和2维块(block)对矩阵进行求和。 #include <stdio.h> #include <stdlib.h> #include <time.h> #i…...

深度学习中CUDA环境安装教程
首先说明,本人是小白,一次安装,可能有不对的地方,望包含。 安装CUDA 因为我们是深度学习,很多时候要用到gpu进行训练,所以我们需要一种方式加快训练速度。 通俗地说,CUDA是一种协助“CPU任务分…...

IDEA的常用设置
目录 一、显示顶部工具栏 二、设置编辑区字体按住鼠标滚轮变大变小(看需要设置) 三、设置自动导包和优化导入的包(有的时候还是需要手动导包) 四、设置导入同一个包下的类,超过指定个数的时候,合并为*&a…...
【VUE+ElementUI】通过接口下载blob流文件设置全局Loading加载进度
下载Blob流文件,并以服务形式显示文件下载进度 1、下载接口 增加 config参数,并用...config将该属性加入到请求中; xxapi.js文件中设置downloadFile下载接口 // 下载文件 export function downloadFile(data, config) {return request({ur…...
算法的五个重要特性和4个基本标准
五个特性: 1、有穷性:一个算法必须执行有穷步后结束、 2、确定性:对于每种情况下所应执行的操作,在算法中都应该有确切的规定,不会产生二义性, 使得算法的执行者和阅读者都能明确其含义以及如何执行。 3、…...
svelte5中使用react组件
在svelet5中导入并使用react组件库 svelte5中使用react组件 svelte5中使用react组件 在svelet5中导入并使用react组件库, 示例项目地址:https://github.com/shenshouer/my-svelte-react 在svelte5中当前还有问题,无法将children传递到react中渲染 使用…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...