Bean 的作用域和生命周期
Bean的作用域
公共bean :
@Bean
public User user() {
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
修改:
public void printUser() {
System.out.println(user);
User myUser = user;
myUser.setName("李四");
System.out.println("myUser ->" + myUser);
System.out.println("user ->" + user);
}
结果 :
原因分析 :
因为 Bean 的默认情况是单例状态(singleton) , 也就是所有人使用的都是同一个对象
作用域的定义 :
Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式 , 比如 singleton 单例作用域 , 就表示 Bean 在整个 Spring 中只有一份 , 他是全局共享的 , 那么当其他人修改了这个值之后 , 那么另一个人读取到的就是被修改的值 .
Spring Bean 作用域(Scope)
-
单例模式 : singleton (默认模式)
该作用域下的 Bean 在 IOC 容器中只存在一个实例 : 获取 Bean及配置 Bean都是同一个对象
场景 :通常无状态的Bean 使用该作用域 . 无状态表示 Bean 的对象的属性状态不需要更新
-
原型模式 : prototype
每次该作用域下的 Bean 的请求都会创建新的实例 : 获取 Bean及装配Bean都是新的对象实例
场景 : 通常有状态的 Bean 使用该作用域
-
请求作用域 : request , 每次 HTTP 请求 , 都会创建一个新的 Bean对象 [适用于 Spring MVC/Spring Web]
场景 : 一次 http 的请求和响应的共享 Bean
-
会话作用域 : session , 每次 Session 会话共享一个 Bean [Spring MVC]
在一个HTTP session 中 , 定义一个Bean实例
场景 : 用户会话的共享 Bean , 比如 : 记录一个用户的登录信息
-
全局作用域 : application , 一个 http servlet context 中 共享一个 bean [spring mvc]
场景 :Web 应用的上下文信息 , 比如 : 记录一个应用的共享信息
-
webscoket : 网络长连接 , 只适用于 Spring WebSocket 项目
在一个HTTP WebSocket 的生命周期中 , 定义一个Bean
WebSocket 的每次会话中 , 保存了一个 Map 结构的头信息 , 将用来包裹客户端消息头 , 第一次初始化后 , 直到WebSocket 结束都是同一个Bean
作用域设置
直接设置值 : @Scope(“prototype”) : 默认是单例的 , 需要设置成多例模式
使用枚举设置 : @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Spring 的执行流程
Bean 的生命周期
从诞生到销毁的过程
- 实例化Bean (为Bean 分配空间)
- 设置属性 (Bean 注入和装配)
- Bean 初始化
- 实现了各种 Aware 通知的方法 , 如BeanNameAware , BeanFactoryAware , ApplicationContextAware 的接口
- 执行 BeanPostProcessor 初始化前置方法;
- 执行 @PostConstruct 初始化方法 , 依赖注入操作之后被执行
- 执行自己指定的 init-method 方法(如果指定)
- 执行 BeanPostProcessor 初始化后置方法
- 使用 Bean
- 销毁 Bean
为什么设置属性 在 初始化之前
在 Bean 的实例化阶段 , 会先创建一个空对象 , 然后为其设置属性值 , 这是因为在创建Bean 实例时 , 可能需要一些默认的属性值或者依赖注入的属性值 . 在这个阶段 , 容器还没有执行其他的初始化阶段操作 , 因此设置属性的代码可以放在初始化之前.
如果将属相的设置放在初始化之后 , 可能会导致初始化方法中需要使用到这些属性值的情况下出现问题 . 因此设置属性在初始化之前 . 确保在初始化过程中能够正确进行 .
初始化和实力化的区别 : 实例化和属性设置是java 级别的系统"事件",其操作过程是不可人工干预和修改;而初始化是给开发者提供的 ,可以在实例化之后 ,类加载完成之前进行自定义"事件"处理
例 :
- 先买房(实例化,从⽆到有);
- 装修(设置属性);
- 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
- ⼊住(使⽤ Bean);
- 卖出去(Bean 销毁)。
例 :
- 先买房(实例化,从⽆到有);
- 装修(设置属性);
- 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
- ⼊住(使⽤ Bean);
- 卖出去(Bean 销毁)。