Spring Bean 的作用域(Scope)
1. Singleton(单例)
-
含义:在 Spring IoC 容器中,Bean 的对象始终为单实例。
-
创建时机:IoC 容器初始化时创建。
-
特点:
-
所有请求该 Bean 的地方都会返回同一个实例。
-
适用于无状态的 Bean,例如工具类、配置类等。
-
-
spring-scope.xml代码:
<bean id="student" class="com.atguigu.spring.pojo.Student" scope="singleton">
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
</bean>
-
定义 Bean:
-
使用
<bean>
标签定义一个 Bean。 -
id="student"
:指定 Bean 的唯一标识符,用于在 Spring 容器中查找该 Bean。 -
class="com.atguigu.spring.pojo.Student"
:指定 Bean 的完整类名,Spring 会根据该类创建对象。
-
-
设置作用域:
-
scope="singleton"
:指定 Bean 的作用域为单例(默认值)。-
单例模式下,Spring 容器中只会创建一个
Student
实例,并且每次请求该 Bean 时都会返回同一个实例。
-
-
-
注入属性值:
-
使用
<property>
标签为 Bean 的属性赋值。 -
name="sid"
:指定属性名,对应Student
类中的sid
字段。 -
value="1001"
:为sid
属性赋值。 -
name="sname"
:指定属性名,对应Student
类中的sname
字段。 -
value="张三"
:为sname
属性赋值。
-
-
ScopeTest.java测试结果:
@Test
public void testScope() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-scope.xml");
Student student1 = ioc.getBean(Student.class);
Student student2 = ioc.getBean(Student.class);
System.out.println(student1 == student2); // 输出 true
}
-
加载 Spring 配置文件:
-
使用
ClassPathXmlApplicationContext
加载spring-scope.xml
配置文件。 -
ApplicationContext
是 Spring 的核心容器,负责管理 Bean 的生命周期和依赖注入。
-
-
获取 Bean 实例:
-
通过
ioc.getBean(Student.class)
从 Spring 容器中获取Student
的实例。 -
由于
scope="singleton"
,student1
和student2
是同一个对象。
-
-
验证作用域:
在 Java 中,
==
运算符用于比较两个对象的引用(即内存地址),而不是对象的内容。如果两个对象的引用相同(指向同一块内存地址),则==
返回true
;否则返回false
。student1 == student2
的比较结果直接反映了 Spring 容器中 Bean 的作用域行为。
2. Prototype(多例)
-
含义:每次从 IoC 容器中获取该 Bean 时,都会创建一个新的实例。
-
创建时机:每次调用
getBean()
方法时创建。 -
特点:
-
适用于有状态的 Bean,例如用户会话、请求处理等。
-
-
spring-scope.xml代码:
<bean id="student" class="com.atguigu.spring.pojo.Student" scope="prototype">
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
</bean>
- ScopeTest.java测试结果:
@Test
public void testScope() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-scope.xml");
Student student1 = ioc.getBean(Student.class);
Student student2 = ioc.getBean(Student.class);
System.out.println(student1 == student2); // 输出 false
}
总结对比
作用域 | 含义 | 创建时机 | 适用场景 |
---|---|---|---|
singleton |
单例,IoC 容器中只有一个实例 | IoC 容器初始化时 | 无状态的 Bean,如工具类、配置类 |
prototype |
多例,每次获取时创建一个新实例 | 每次调用 getBean() 时 |
有状态的 Bean,如用户会话、请求处理 |
request |
每个 HTTP 请求一个实例 | 每次 HTTP 请求时 | 请求相关的数据 |
session |
每个 HTTP 会话一个实例 | 每次 HTTP 会话时 | 会话相关的数据 |