此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10! |
Spring IoC 容器管理一个或多个 Bean。这些 Bean 是使用
提供给容器的配置元数据(例如,以 XML 定义的形式)。<bean/>
在容器本身中,这些 Bean 定义表示为对象,其中包含(除其他信息外)以下元数据:BeanDefinition
-
包限定的类名:通常为 Bean 正在定义。
-
Bean 行为配置元素,说明 Bean 在 容器(范围、生命周期回调等)。
-
对 Bean 完成其工作所需的其他 Bean 的引用。这些 引用也称为协作者或依赖项。
-
要在新创建的对象中设置的其他配置设置,例如大小 池的限制或要在管理 Bean 的 Bean 中使用的连接数 连接池。
此元数据转换为构成每个 Bean 定义的一组属性。 下表描述了这些属性:
财产 | 解释... |
---|---|
类 |
|
名字 |
|
范围 |
|
构造函数参数 |
|
性能 |
|
自动接线模式 |
|
延迟初始化模式 |
|
初始化方法 |
|
销毁方式 |
除了包含有关如何创建特定
bean,实现还允许注册现有的
在容器外部创建的对象(由用户创建)。这是通过访问
ApplicationContext 通过该方法,该方法返回
实现。 支持
此注册通过和方法。但是,典型的应用程序仅使用通过常规定义的 bean
Bean 定义元数据。ApplicationContext
BeanFactory
getBeanFactory()
DefaultListableBeanFactory
DefaultListableBeanFactory
registerSingleton(..)
registerBeanDefinition(..)
Bean 元数据和手动提供的单例实例需要尽早注册 为了让容器在自动接线过程中正确地推理它们 和其他内省步骤。同时覆盖现有元数据和现有 在某种程度上支持单例实例,在 运行时(与工厂的实时访问同时进行)不受官方支持,并且可能 导致并发访问异常和/或 Bean 容器中的状态不一致。 |
财产 | 解释... |
---|---|
类 |
|
名字 |
|
范围 |
|
构造函数参数 |
|
性能 |
|
自动接线模式 |
|
延迟初始化模式 |
|
初始化方法 |
|
销毁方式 |
Bean 元数据和手动提供的单例实例需要尽早注册 为了让容器在自动接线过程中正确地推理它们 和其他内省步骤。同时覆盖现有元数据和现有 在某种程度上支持单例实例,在 运行时(与工厂的实时访问同时进行)不受官方支持,并且可能 导致并发访问异常和/或 Bean 容器中的状态不一致。 |
命名 Bean
每个 Bean 都有一个或多个标识符。这些标识符在 托管 Bean 的容器。Bean 通常只有一个标识符。但是,如果它 需要多个,多余的可以被视为别名。
在基于 XML 的配置元数据中,使用属性、属性或
两者都指定 Bean 标识符。该属性允许您只指定一个 .
通常,这些名称是字母数字(“myBean”、“someService”等),但它们
也可以包含特殊字符。如果要为
bean,也可以在属性中指定它们,用逗号()分隔,
分号 () 或空格。尽管该属性被定义为一种类型,但 Bean 的唯一性是由容器强制执行的,而不是由 XML 强制执行的
解析 器。id
name
id
id
name
,
;
id
xsd:string
id
您不需要为 bean 提供 a 或 an。如果未显式提供 或,则容器将为该 Bean 生成唯一名称。然而
如果您想通过名称引用该 Bean,请通过使用 元素或
服务定位器样式查找时,必须提供名称。
不提供名称的动机与使用内部 bean 和自动连接协作者有关。name
id
name
id
ref
通过类路径中的组件扫描,Spring 会为 unnamed 生成 bean 名称
组件,遵循前面描述的规则:本质上,采用简单的类名
并将其初始字符转换为小写。然而,在(不寻常的)特殊
当有多个字符以及第一个和第二个字符时的情况
是大写的,保留了原来的大小写。这些规则与
定义者 (Spring 在此处使用)。java.beans.Introspector.decapitalize |
在 Bean 定义之外对 Bean 进行别名
在 Bean 定义本身中,您可以使用
属性指定的最多一个名称和任意数量的其他名称的组合
属性中的名称。这些名称可以是同一 Bean 的等效别名
并且在某些情况下很有用,例如让应用程序中的每个组件
使用特定于该组件的 Bean 名称来引用公共依赖关系
本身。id
name
指定实际定义 Bean 的所有别名并不总是足够的,
然而。有时需要为已定义的 Bean 引入别名
别处。这在拆分配置的大型系统中很常见
在每个子系统中,每个子系统都有自己的一组对象定义。
在基于 XML 的配置元数据中,可以使用该元素完成
这。以下示例演示如何执行此操作:<alias/>
<alias name="fromName" alias="toName"/>
在这种情况下,名为 bean (in the same container) 的 bean 也可以,
使用此别名定义后,称为 。fromName
toName
例如,子系统 A 的配置元数据可以通过
的名称 。子系统 B 的配置元数据可以参考
名称为 的 DataSource。编写主应用程序时
使用这两个子系统,主应用程序通过
的名称 。要让这三个名称都引用同一个对象,您可以
将以下别名定义添加到配置元数据中:subsystemA-dataSource
subsystemB-dataSource
myApp-dataSource
<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>
现在,每个组件和主应用程序都可以通过名称引用 dataSource 这是独一无二的,并保证不会与任何其他定义发生冲突(有效地 创建一个命名空间),但它们引用的是同一个 bean。
通过类路径中的组件扫描,Spring 会为 unnamed 生成 bean 名称
组件,遵循前面描述的规则:本质上,采用简单的类名
并将其初始字符转换为小写。然而,在(不寻常的)特殊
当有多个字符以及第一个和第二个字符时的情况
是大写的,保留了原来的大小写。这些规则与
定义者 (Spring 在此处使用)。java.beans.Introspector.decapitalize |
实例化 Bean
Bean 定义本质上是创建一个或多个对象的配方。这 容器在询问时查看命名 Bean 的配方并使用配置 由该 Bean 定义封装的元数据,用于创建(或获取)实际对象。
如果使用基于 XML 的配置元数据,则指定对象的类型(或类)
即在元素的属性中实例化。此属性(在内部是实例上的属性)通常是必需的。(有关例外情况,请参阅使用实例工厂方法实例化和 Bean 定义继承。
您可以通过以下两种方式之一使用该属性:class
<bean/>
class
Class
BeanDefinition
Class
-
通常,指定要构造的 Bean 类,其中容器 它本身通过反射性地调用其构造函数来直接创建 Bean,在某种程度上 等同于带有运算符的 Java 代码。
new
-
指定包含工厂方法的实际类,即 调用以创建对象,在不太常见的情况下,容器调用类上的工厂方法来创建 Bean。返回的对象类型 从工厂方法的调用可以是相同的类或另一个类 完全类。
static
static
static
使用构造函数进行实例化
当您通过构造函数方法创建 Bean 时,所有普通类都可以通过 和 与 Spring 兼容。也就是说,正在开发的类不需要实现 任何特定的接口或以特定方式编码。只需指定 Bean 类应该就足够了。但是,具体取决于您用于该特定 IoC 的类型 bean,您可能需要一个默认的(空)构造函数。
Spring IoC 容器几乎可以管理您希望它管理的任何类。是的 不仅限于管理真正的 JavaBeans。大多数 Spring 用户更喜欢实际的 JavaBeans 仅建模默认(无参数)构造函数和适当的 setter 和 getter 在容器中的属性之后。你也可以有更多异国情调的非豆式 容器中的类。例如,如果需要使用旧连接池 绝对不遵守 JavaBean 规范,Spring 可以将其管理为 井。
使用基于 XML 的配置元数据,可以按如下方式指定 Bean 类:
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
有关向构造函数提供参数的机制的详细信息(如果需要) 并在构造对象后设置对象实例属性,请参阅注入依赖项。
使用静态工厂方法进行实例化
在定义使用静态工厂方法创建的 Bean 时,请使用该属性指定包含工厂方法和属性的类
named 指定工厂方法本身的名称。你应该是
能够调用此方法(使用可选参数,如后面所述)并返回一个 live
对象,随后将其视为通过构造函数创建的对象。
这种 Bean 定义的一个用途是在遗留代码中调用工厂。class
static
factory-method
static
以下 Bean 定义指定将通过调用
工厂方法。定义未指定返回对象的类型(类),
而是包含工厂方法的类。在此示例中,该方法必须是方法。下面的示例演示如何
指定工厂方法:createInstance()
static
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>
下面的示例显示了一个可以使用前面的 Bean 定义的类:
-
Java
-
Kotlin
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
class ClientService private constructor() {
companion object {
private val clientService = ClientService()
@JvmStatic
fun createInstance() = clientService
}
}
有关向工厂方法提供(可选)参数的机制的详细信息 并在对象出厂后设置对象实例属性, 请参阅依赖项和配置详细信息。
使用实例工厂方法进行实例化
与通过静态工厂方法实例化类似,使用实例工厂方法实例化调用非静态
方法从容器中获取现有 Bean 以创建新 Bean。要使用此内容,请执行此操作
mechanism,将属性留空,并在属性中
指定当前(或父或祖先)容器中 Bean 的名称,该容器包含
要调用以创建对象的实例方法。设置名称
factory 方法本身与属性。以下示例显示
如何配置这样的 Bean:class
factory-bean
factory-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
-
Kotlin
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
class DefaultServiceLocator {
companion object {
private val clientService = ClientServiceImpl()
}
fun createClientServiceInstance(): ClientService {
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
-
Kotlin
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;
}
}
class DefaultServiceLocator {
companion object {
private val clientService = ClientServiceImpl()
private val accountService = AccountServiceImpl()
}
fun createClientServiceInstance(): ClientService {
return clientService
}
fun createAccountServiceInstance(): AccountService {
return accountService
}
}
这种方法表明,工厂 Bean 本身可以通过以下方式进行管理和配置 依赖注入 (DI)。 请参阅依赖项和配置的详细信息。
在 Spring 文档中,“factory bean”指的是在
Spring 容器,并通过实例或静态工厂方法创建对象。相比之下,(注意大写)指的是特定于 Spring 的 FactoryBean 实现类。FactoryBean |
确定 Bean 的运行时类型
确定特定 Bean 的运行时类型并非易事。中的指定类
Bean 元数据定义只是一个初始类引用,可能会组合在一起
使用声明的工厂方法或作为可能导致
Bean 的运行时类型不同,或者在实例级别的情况下根本不设置
factory 方法(改为通过指定名称进行解析)。
此外,AOP 代理可能会使用基于接口的代理包装 Bean 实例,并带有
目标 Bean 的实际类型(仅其实现的接口)的有限曝光。FactoryBean
factory-bean
要了解特定 Bean 的实际运行时类型,推荐的方法是
对指定 Bean 名称的调用。这需要以上所有条件
大小写,并返回调用的对象类型
将返回相同的 Bean 名称。BeanFactory.getType
BeanFactory.getBean
在 Spring 文档中,“factory bean”指的是在
Spring 容器,并通过实例或静态工厂方法创建对象。相比之下,(注意大写)指的是特定于 Spring 的 FactoryBean 实现类。FactoryBean |