
2024好事发生
Java面试宝典:MongoDB实战技巧 作者:忆遂愿
https://cloud.tencent.com/developer/article/2466159?shareByChannel=link
文章对 MongoDB 知识的全面阐述,质量很高。从基本概念、Java 驱动使用、数据一致性事务处理,到数据模型设计、技术集成和存储图片优势等方面讲解详细、条理清晰,体现出作者深入的理解。推荐给各位需要的同学。
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
在Spring中,获取一个单例Bean需要经过从缓存中查询、创建对象、依赖注入、将对象放入单例Bean缓存等步骤。当没有循环依赖时,这个流程运行得很好。但一旦出现循环依赖,就会出现问题。例如,Bean C在依赖注入Bean B时,缓存中没有Bean B(因为此时Bean B还没有完成创建),只能创建Bean B,从而导致重复创建(因为此时Bean B已经在创建中)。
Spring通过引入三级缓存机制来解决循环依赖问题:
下面是一个简化的源码实现,用于展示Spring如何解决循环依赖问题:
java复制代码
public class DefaultSingletonBeanRegistry {
// 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 判断Bean是否正在创建中
private final Set<String> singletonsCurrentlyInCreation = new HashSet<>(16);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
return singletonObject;
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
public void beforeSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.add(beanName);
}
public void afterSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.remove(beanName);
this.singletonObjects.put(beanName, this.earlySingletonObjects.remove(beanName));
}
}java复制代码
@Component
public class A {
@Autowired
private B b;
}
@Component
public class B {
@Autowired
private A a;
}在这个例子中,A和B相互依赖,Spring通过三级缓存机制能够成功解决循环依赖问题。
java复制代码
@Component
public class A {
@Autowired
private B b;
}
@Component
@Aspect
public class B {
@Autowired
private A a;
}在这个例子中,B是一个切面,Spring会在创建B的代理对象时处理循环依赖问题。
通过本文的深入剖析,相信你对Spring IoC循环依赖的底层源码有了全新的认识。Spring通过三级缓存机制巧妙地解决了循环依赖问题,使得开发者能够更加方便地管理Bean的依赖关系。同时,我们也看到了Spring在解决复杂问题时所展现出的智慧和优雅。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。