华为OD技术面真题 - JAVA开发- spring框架 - 7

文章目录

Spring中单例Bean会存在线程安全吗?

分情况分状态讨论:

  1. 创建:spring容器会保证Bean创建过程中的线程安全。
  2. 使用:
    1. 无状态的Bean是线程安全的。特点:
      • 没有成员变量或者不被修改。
      • 方法只使用局部变量
    2. 有状态的Bean。
      1. 存在成员变量并且存在修改
      2. 修改函数未加锁或其它同步操作。

如何保证单例Bean线程安全

出现线程安全的原因本质是:多个线程同时并发读写同一份可变共享数据,且没有任何同步控制。

  1. 保证创建的Bean是无状态的。只读操作是线程安全
  2. 使用ThreadLocal每个线程操作单独的副本或者将Singleton转换为Prototype。将共享转换为不共享
  3. 加锁或者使用原子类/线程安全类。进行同步控制

什么是循环依赖?Spring可以解决哪些类型的循环依赖

循环依赖:多个对象之间相互依赖,形成一个闭环。例如A->B->A,以下一个例子为例

复制代码
@Component
class A {
    @Autowired
    private B b;
}

@Component
class B {
    @Autowired
    private A a;
}

可以自行解决的循环依赖类型

  • A/B的对应属性采用setter方法注入
  • A/B对应属性采用属性自动注入
    不可以解决的循环依赖的类型:
  • AB为多例Bean
  • A/B对应属性都采用构造器注入
  • A/B对应属性存在构造器注入(例如A类采用构造器注入,B中采用属性/setter方法注入)

Spring是如何解决循环依赖的

Spring借助三级缓存机制解决循环依赖。spring中定义了三个缓存

  • singletonObjects: 一级缓存用于存放完全初始化好的Bean
  • earlySingletonObjects: 二级缓存用于存放提前暴露的bean
  • singletonFactories:三级缓存用于存放Bean工厂。

解决三级缓存解决缓存依赖的流程,以A/B类为例:

  1. 实例化A,此时A为空壳对象。放入三级缓存singletonFactories
  2. A进行输入注入,发现依赖B对象。调用getSingleton('B')获取,此时B还未创建,会实例化B。
  3. 实例化B,B也放入三级缓存中。此时发现B需要A,调用getSingleton('A')获取,会命中三级缓存返回A的早期对象。将A早期对象放入二级缓存 earlySingletonObjects 删除三级缓存中的 A.
  4. B获取到A早期对象之后,完成完整创建。放入一级缓存。此时回到A
  5. A获取到一级缓存中的B,A初始化完成。A也放入一级缓存。
相关推荐
揣一尾游鱼yu12 分钟前
Spring上(IOC)笔记
java·笔记·spring·ioc
荣码23 分钟前
长上下文与大文档处理:200页PDF怎么喂给AI,我踩了4个坑
java·python
樱花树下的数学喵24 分钟前
手写简易 STL string|C++ 字符串底层实现
开发语言·c++
极限挑战哥1 小时前
共享电单车联营平台分账架构实践:二清合规与自动分账零人工方案
java·大数据·人工智能·微信小程序·架构·微信公众平台
jimy11 小时前
C++ 报错的 qualifiers 的意思
开发语言·c++
皮皮林5511 小时前
比 VMware 更快,更轻的虚拟机,横空出世!
java
Thomas.Sir1 小时前
第13课:MyBatis-Plus整合SpringBoot4.x,分页、条件查询、逻辑删除实战
java·spring boot
meiying88382 小时前
多快递公司快递单号批量查询接口怎么对接?Python 聚合查询实现
java·大数据·python
古法安卓2 小时前
Android-GPU压测工具
android·java·android studio
不积跬步无以至千里mmbb262 小时前
rust_analysis
开发语言·后端·rust