八股训练营第 39 天 | Bean 的作用域?Bean 的生命周期?Spring 循环依赖是怎么解决的?Spring 中用到了那些设计模式?

Spring核心机制详解

Bean 的作用域?

Spring IoC 容器的对象称之为 Bean。Bean 的作用域就是对象在应用程序中的生命周期和可见范围,通常有以下几种类型:

  1. 单例:是默认的作用域。如果一个 Bean 的作用域为 Singleton,那么 IoC 容器中只会存在一个共享的 Bean 实例。当对 Bean 进行请求时,如果 ID 与该 Bean 定义相匹配,那么会返回同一个 Bean 实例。
  2. 原型:如果一个 Bean 的作用域为 Prototype,那么一个 Bean 会对应多个实例对象。每次对该 Bean 的请求都会创建一个新的 Bean 实例。
  3. 请求:一个 HTTP 请求对应一个 Bean 实例。每个 HTTP 请求都会创建一个新的 Bean 实例。且该 Bean 仅在请求期间有效。
  4. 会话:一个 HTTP 会话对应一个 Bean 实例。Bean 的生命周期与会话的生命周期相同。
  1. 应用程序:对于定义在 ServletContext中的 Bean,整个 Web 应用程序共享一个 Bean 实例。
  2. Websocket:WebSocket生命周期内,每个 WebSocket 会话拥有一个 Bean 实例。

Bean的生命周期?

Bean 的生命周期,就是 Bean 从创建到销毁的整个过程,包含以下几个步骤:

  1. 实例化 Bean:Spring 容器通过构造器或者工厂方法创建 Bean 实例。
  2. 设置属性:容器注入 Bean 的属性。这些属性可能是其他 Bean 的引用,也可以是一些简单的配置值。
  3. 检查 Aware 接口并设置相关依赖:如果 Bean 实现了 BeanNameAware 或 BeanFactoryAware 接口,容器会调用相应的 setBeanName 或 setBeanFactory 方法。
  4. BeanPostProcessor:在 Bean 的属性设置完毕之后,容器会调用所有注册了 BeanPostProcessor 的 postBeanBeforeInitialization 方法。
  5. 初始化 Bean:如果 Bean 实现了 InitializingBean 接口,容器会调用 afterPropertiesSet 方法;如果 Bean 定义了 init-method,那么容器也会调用这个方法。
  6. BeanPostProcessor 的二次调用:容器会再次调用所有注册了 BeanPostProcessor 的 postBeanAfterInitialization 方法。这是在初始化 Bean 之后调用的。
  7. 使用 Bean:此时 Bean 已经设置完毕,可以被应用程序所使用。
  8. 处理 DisposableBean 和 destroy-method:当容器关闭时,如果 Bean 实现了 DisposableBean 接口,则容器会调用相应的 destroy 方法;如果 Bean 定义了 destroy-method,容器也会调用这个方法。
  9. Bean 销毁:最后,Bean 被 Spring 容器销毁,结束了它的生命周期。

Spring 循环依赖是怎么解决的?

  1. 什么是循环依赖
    循环依赖是指两个或者两个以上的 Bean 互相持有对方,最终形成闭环。比如 Bean A 依赖于 Bean B,Bean B 又依赖于 Bean A。

  2. 如何解决

  • 字段注入或 Setter 注入:使用三级缓存来解决循环依赖。
    • 首先,Spring 容器会实例化一个 Bean(这个 Bean 是已通过构造器创建,但属性尚未填充),然后注册一个 singletonFactory 到三级缓存,这个工厂会在需要时返回该 Bean 的早期引用。
    • 当为该 Bean 填充属性时,如果属性依赖其他 Bean,而其他 Bean 又依赖当前 Bean,就会尝试从缓存中获取当前 Bean。优先从一级缓存获取完全初始化的 Bean。如果未找到,就尝试从二级缓存获取该 Bean 的早期引用。如果也未找到,就调用三级缓存中的工厂,生成早期引用并放入二级缓存。
    • 当 Bean 的属性填充和初始化全部完成后,就会把完全初始化的 Bean 放入一级缓存中,并清理掉在二级、三级缓存中的临时引用。
  • 构造器注入:Spring 容器无法解决构造器注入造成的循环依赖。但是可以使用 @Lazy 懒加载方法,延迟 Bean 的加载。知道它被实际使用时才创建。

① 一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的 Bean 对象
② 二级缓存:缓存早期的 Bean 对象(生命周期还没走完)
③ 三级缓存:缓存的是 ObjectFactory,表示对象工厂,用来创建某个对象的

Spring 中用到了那些设计模式?

  1. 工厂设计模式:Spring 使用工厂设计模式,通过 BeanFactory 和 ApplicationContext 创建 Bean 对象。
  2. 代理设计模式:Spring AOP 就是代理功能实现。
  3. 单例设计模式:Spring 中的 Bean 默认是单例的。
  4. 模板方法模式:Spring 中的 jdbcTemplate、hiberateTemplate 等以 Template 结尾的操作数据库的类,它们就采用了模板模式。
  5. 包装器设计模式:我们的项目会连接多个数据库,不同的客户每次访问会根据需要访问不同的数据库,这种模式可以让我们根据客户的需求动态切换不同的数据源。
  6. 观察者模式:Spring 中的事件驱动模型就是观察者模式很经典的一个应用。
  7. 适配器模式:Spring AOP 的增强和通知使用到了适配器模式。Spring MVC 也使用适配器模式来适配 Controller。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值