博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring循环依赖,解决beans in the application context form a cycle
阅读量:4041 次
发布时间:2019-05-24

本文共 1495 字,大约阅读时间需要 4 分钟。

spring循环依赖简单理解就是类A中引用B,B引用C,C中引用了A,这样构成了循环。

spring中解决循环依赖主要靠三级本地缓存解决

第一级缓存singletonObjects里面放置的是缓存实例化好的单例对象。

第二级earlySingletonObjects里面存放的是提前曝光的单例对象(没有完全装配好)。

第三级singletonFactories里面存放的是要被实例化的对象的对象工厂

/** Cache of singleton objects: bean name --> bean instance(缓存单例实例化对象的Map集合) */ private final Map
singletonObjects = new ConcurrentHashMap
(64); /** Cache of singleton factories: bean name --> ObjectFactory(单例的工厂Bean缓存集合) */ private final Map
singletonFactories = new HashMap
(16); /** Cache of early singleton objects: bean name --> bean instance(早期的单身对象缓存集合,未完全事例好) */ private final Map
earlySingletonObjects = new HashMap
(16); /** Set of registered singletons, containing the bean names in registration order(单例的实例化对象名称集合) */ private final Set
registeredSingletons = new LinkedHashSet
(64);

具体流程原理参考:       

具体报错的例子是这样的:

QueueMessageCommService通过构造方法注入QueueFieldService,但是QueueFieldService中注入的bean中也注入了QueueMessageCommService,构成了循环。

spring在自动装载时报错beans in the application context form a cycle,与final有关(jdk1.8不同版本有的报错,有的不报错)。

如下图修改后:就不报错了,完全交给spring去装载注入Bean

 

解决循环依赖的办法:

1、@Autowired   交给spring完全处理

2、setter 单例方式singleton  处理这种方式是bean先实例化后再进行属性填充,这样避免了实例时形成循环

3、setter 原型prototype  代表是有状态的bean,spring 无法完成依赖注入,因为不对它进行缓存(三级缓存的对象)

这样就需要调用Bean中方法(有引用对象使用)之前,先掉set方法赋值(引用对象),防止出现null。

scope="prototype" 意思是 每次请求都会创建一个实例对象。两者的区别是:有状态的bean都使用Prototype作用域,无状态的一般都使用singleton单例作用域。

     spring事例化图:

更多setter方式详细见:

 

 

你可能感兴趣的文章
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>