Bean 的作用域和生命周期

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)

  1. 单例模式 : singleton (默认模式)

    该作用域下的 Bean 在 IOC 容器中只存在一个实例 : 获取 Bean及配置 Bean都是同一个对象

    场景 :通常无状态的Bean 使用该作用域 . 无状态表示 Bean 的对象的属性状态不需要更新

  2. 原型模式 : prototype

    每次该作用域下的 Bean 的请求都会创建新的实例 : 获取 Bean及装配Bean都是新的对象实例

    场景 : 通常有状态的 Bean 使用该作用域

  3. 请求作用域 : request , 每次 HTTP 请求 , 都会创建一个新的 Bean对象 [适用于 Spring MVC/Spring Web]

    场景 : 一次 http 的请求和响应的共享 Bean

  4. 会话作用域 : session , 每次 Session 会话共享一个 Bean [Spring MVC]

    在一个HTTP session 中 , 定义一个Bean实例

    场景 : 用户会话的共享 Bean , 比如 : 记录一个用户的登录信息

  5. 全局作用域 : application , 一个 http servlet context 中 共享一个 bean [spring mvc]

    场景 :Web 应用的上下文信息 , 比如 : 记录一个应用的共享信息

  6. webscoket : 网络长连接 , 只适用于 Spring WebSocket 项目

    在一个HTTP WebSocket 的生命周期中 , 定义一个Bean

    WebSocket 的每次会话中 , 保存了一个 Map 结构的头信息 , 将用来包裹客户端消息头 , 第一次初始化后 , 直到WebSocket 结束都是同一个Bean

作用域设置

直接设置值 : @Scope(“prototype”) : 默认是单例的 , 需要设置成多例模式

使用枚举设置 : @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Spring 的执行流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFb8AkPj-1689591805591)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1689583949294.png)]

Bean 的生命周期

从诞生到销毁的过程

  1. 实例化Bean (为Bean 分配空间)
  2. 设置属性 (Bean 注入和装配)
  3. Bean 初始化
    • 实现了各种 Aware 通知的方法 , 如BeanNameAware , BeanFactoryAware , ApplicationContextAware 的接口
    • 执行 BeanPostProcessor 初始化前置方法;
    • 执行 @PostConstruct 初始化方法 , 依赖注入操作之后被执行
    • 执行自己指定的 init-method 方法(如果指定)
    • 执行 BeanPostProcessor 初始化后置方法
  4. 使用 Bean
  5. 销毁 Bean

为什么设置属性 在 初始化之前

​ 在 Bean 的实例化阶段 , 会先创建一个空对象 , 然后为其设置属性值 , 这是因为在创建Bean 实例时 , 可能需要一些默认的属性值或者依赖注入的属性值 . 在这个阶段 , 容器还没有执行其他的初始化阶段操作 , 因此设置属性的代码可以放在初始化之前.

​ 如果将属相的设置放在初始化之后 , 可能会导致初始化方法中需要使用到这些属性值的情况下出现问题 . 因此设置属性在初始化之前 . 确保在初始化过程中能够正确进行 .

初始化和实力化的区别 : 实例化和属性设置是java 级别的系统"事件",其操作过程是不可人工干预和修改;而初始化是给开发者提供的 ,可以在实例化之后 ,类加载完成之前进行自定义"事件"处理

例 :

  1. 先买房(实例化,从⽆到有);
  2. 装修(设置属性);
  3. 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
  4. ⼊住(使⽤ Bean);
  5. 卖出去(Bean 销毁)。

例 :

  1. 先买房(实例化,从⽆到有);
  2. 装修(设置属性);
  3. 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
  4. ⼊住(使⽤ Bean);
  5. 卖出去(Bean 销毁)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值