一、Bean 的六种作用域
在介绍 Bean 的作用域之前,我们先看一下作用域的概念:
定义: 限定程序中变量的可用范围叫做作用域。
结合以上定义,具体到 Bean 对象来说,Bean 的作用域就是指 Bean 在 Spring 整个框架中的作用范围。
在 Spring 中有六种作用域,下面是关于每个作用域的详细介绍:
- Singleton(单例):
- 单例是一种设计模式,指的是在整个应用程序生命周期内只存在一个实例。在Spring框架中,默认情况下,Bean的作用域是Singleton,这意味着每次从Spring容器中获取该Bean时,都会返回相同的实例。
- Prototype(原型):
- 原型是指每次从容器中获取Bean时都会创建一个新的实例。与Singleton不同,原型作用域的Bean在每次请求时都会生成一个新的实例。这对于某些需要隔离状态的Bean非常有用。
- Request(请求):
- 请求作用域是Web应用程序中的一种作用域,它表示每个HTTP请求都会创建一个新的Bean实例。这样的Bean只在处理单个HTTP请求期间存在,适用于Web应用程序中的请求级别依赖。
- Session(会话):
- 会话作用域表示每个用户会话(通常是浏览器会话)都会创建一个新的Bean实例。这意味着用户在应用程序中的不同HTTP请求之间可以共享相同的Bean状态。通常用于保存用户特定的状态信息。
- Application(应用程序):
- 应用程序作用域表示整个Web应用程序生命周期内只创建一个Bean实例。这意味着无论有多少个用户会话,它们都共享相同的Bean实例。通常用于在整个应用程序中共享全局状态。
WebSocket(Web套接字):
- WebSocket是一种用于实现双向通信的协议,允许Web应用程序中的客户端和服务器之间进行实时的、双向的数据传输。WebSocket作用域是一种特殊的作用域,通常用于在WebSocket连接期间存储和管理相关数据。这种作用域通常是与特定WebSocket连接关联的,每个WebSocket连接可以具有自己的作用域。
这里需要注意的是: 其中上述 3、4、5、6
是 Spring MVC 中的值,在普通的 Spring 项目中只有1、2
两种。
二、设置 Bean 的作用域
在 Spring 中使用 @Scope 可以声明 Bean 的作用域,@Scope 既可以修饰方法也可以修饰类,使用@Scope 设置作用域,有两种设置方式:
直接设置值:@Scope(“prototype”)
使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
使用示例:
我们知道,在Spring框架中,默认情况下,Bean的作用域是Singleton,所以默认情况下,如下的 Projecter1 和 Projecter2 获取到的是同一个 Bean 对象,因此 Projecter1 对 Bean 进行的修改,会影响到 Projecter2 获取到的同一个 Bean 对象:
下面我们使用 @Scope(“pototype”) 对 User 进行作用域声明,在进行测试:
@Component public class Users { @Bean("user") @Scope("prototype") // 设置原型作用域 public User user(){ User user = new User(); user.setName("这是初始数据"); return user; } }
三、Bean 的生命周期
所谓的生命周期指的是⼀个对象从诞生到销毁的整个生命过程,Bean 的生命周期分为以下 5 大部分:
- 实例化 Bean。在这个阶段,Bean实例被创建,主要进行内存分配,但还没有被初始化。
- 设置 Bean 属性。在Bean被实例化后,Spring容器会将依赖的其他Bean引用注入到当前Bean中。
- 初始化 Bean。
(1)执行各种通知
(2)执行初始化的前置方法
(3)执行初始化方法
(4)执行初始化的后置方法
- 使用 Bean。
- 销毁 Bean。
注: 先进行依赖注入再进行初始化的设计是为了确保 Bean 的依赖项在初始化之前已经被满足,从而保证Bean在初始化过程中可以访问到它所依赖的其他组件。