Spring5源码 - 09 循环依赖解读
2021/5/31 20:25:44
本文主要是介绍Spring5源码 - 09 循环依赖解读,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 什么是循环依赖
- 模拟循环依赖的问题
- Spring 的循环依赖解决方案(三级缓存)
什么是循环依赖
举个简单的例子
A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。
或者是 A 依赖 B,B 依赖 C,C 又依赖 A,同样的 也是循环依赖
模拟循环依赖的问题
package com.artisan.cycleDepend; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component public class A { @Autowired private B b; @PostConstruct public void init(){ System.out.println("A"); } }
import javax.annotation.PostConstruct; @Component public class B { @Autowired private A a ; @PostConstruct public void init(){ System.out.println("A"); } }
【测试代码】
package com.artisan.cycleDepend; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import java.lang.reflect.Field; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 模拟循环依赖的问题 */ public class CycleDependTest { private static Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); // 一级缓存 private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); public static void main(String[] args) throws InstantiationException, IllegalAccessException { // 模拟Spring 的 解析对象为 BeanDefinition 并放到 BeanDefinitionMap中 RootBeanDefinition a = new RootBeanDefinition(A.class); RootBeanDefinition b = new RootBeanDefinition(B.class); beanDefinitionMap.put("a",a); beanDefinitionMap.put("b",b); // 模拟Spring 的 getBean 循环创建Bean for (String beanName : beanDefinitionMap.keySet()){ getBean(beanName); } } public static Object getBean(String beanName) throws IllegalAccessException, InstantiationException { // 实例化 RootBeanDefinition beanDefinition = (RootBeanDefinition) beanDefinitionMap.get(beanName); Class<?> beanClass = beanDefinition.getBeanClass(); Object o = beanClass.newInstance(); // 属性填充 // 获取声明的字段 Field[] declaredFields = o.getClass().getDeclaredFields(); // 遍历 for (Field declaredField : declaredFields) { // 检查是否有Autowired注解 Autowired annotation = declaredField.getAnnotation(Autowired.class); if (annotation != null){ // private属性 需要设置为true declaredField.setAccessible(true); // 获取属性的名字 String name = declaredField.getName(); // 递归调用getBean获取实例 Object bean = getBean(name); // 字段设置属性 declaredField.set(o,bean); } } // 初始化 init-method 。。。。 // 存入一级缓存 singletonObjects.put(beanName,o); return o; } }
【运行结果】
分析下原因
Spring 的循环依赖解决方案(三级缓存)
这篇关于Spring5源码 - 09 循环依赖解读的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27本地多文件上传的简单教程
- 2024-11-27低代码开发:初学者的简单教程
- 2024-11-27如何轻松掌握拖动排序功能
- 2024-11-27JWT入门教程:从零开始理解与实现
- 2024-11-27安能物流 All in TiDB 背后的故事与成果
- 2024-11-27低代码开发入门教程:轻松上手指南
- 2024-11-27如何轻松入门低代码应用开发
- 2024-11-27ESLint开发入门教程:从零开始使用ESLint
- 2024-11-27Npm 发布和配置入门指南
- 2024-11-27低代码应用课程:新手入门指南