首页 > 其他分享 >Spring如何处理循环依赖问题

Spring如何处理循环依赖问题

时间:2022-12-08 13:34:53浏览次数:85  
标签:缓存 对象 Spring bean 依赖 三级 循环

Spring如何处理循环依赖问题

什么是循环依赖:

就是多个bean之间相互依赖,形成了一个闭环,比如beanA需要引用BeanB,BeanB需要引用BeanA,形成循环关系。一般默认在单例模式中,属性相互影响的场景。(多个对象之间存在循环的引用关系,在初始化过程当中,就会出现“ 先有蛋还是先有鸡 ”的问题)

依赖注入的两种方式:

  1. 构造方法注入【不适合解决循环依赖】 构造器循环依赖是无法解决的,如果想让构造器支持循环依赖,是不可能的。

  2. set方法注入

spring bean发生循环依赖有三种形式:互相依赖、三者之间及其以上的依赖、自我依赖。

如何解决循环依赖:

  1. 使用@Lazy注解:解决构造方法造成的循环依赖问题

    @Lazy注解: 当@Lazy 放在类上,表示在启动的时候不会创建bean对象,当使用的时候才会创建; 当@Lazy 放在@Bean注解的方法上,表示在启动的时候不会创建bean对象,当使用的时候才会创建; 当@Lazy 放在@Autowired注解的属性上, 并不会直接给属性赋上真正的值,只是会赋值一个代理对象,当真正使用到这个属性的时候,才回去容器中找到一个符合的对象。在使用的时候,也会先执行代理对象的逻辑,然后再是真正bean对象的逻辑; 使用场景:循环依赖的时候可以在循环依赖的对象加上@Lazy注解; 写在方法或者方法参数前面上,效果和写在属性上、一样的,开始注入的只是代理对象,当真正调用的时候才会调用对应对象的逻辑 写在构造方法或者构造方法参数前面上,同上。

     

  2. 使用三级缓存

    利用缓存机制解决循环依赖问题,spring设计了三级缓存解决循环依赖的问题,分别是一级缓存:singletonObjects;二级缓存:earlySingletonObjects;三级缓存:singletonFactories;

    一级缓存:singletonObjects,存放初始化后的单例对象;

    二级缓存:earlySingletonObjects,存放实例化,未完成初始化的单例对象(未完成属性注入的对象);

    三级缓存:singletonFactories,存放ObjectFactory对象(代理对象);

     

    三级缓存之间逐级取,流程如下

    1、getBean()获取实例,Spring首先从一级缓存singletonObjects中获取;

    2、如果获取不到,就从二级缓存earlySingletonObjects中获取,如果还是获取不到意味着bean没有实例化;

    3、这时singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取;(代理也是从三级缓存生产的)

    4、如果从三级缓存中获取到就从singletonFactories中移除,并放入earlySingletonObjects中。其实也就是从三级缓存移动到了二级缓存;

    5、这个bean存在会等待下一次轮寻的时候去赋值(解析@Autowared,@Resource)注解等,属性赋值完成后,将bean存入一级缓存;

    解决循环依赖简单的流程图:

     

 

 

转载至:

https://www.cnblogs.com/huangtiing/p/16743815.html

https://blog.csdn.net/DQWERww/article/details/126128229

https://blog.csdn.net/yaoyaochengxian/article/details/118636958

标签:缓存,对象,Spring,bean,依赖,三级,循环
From: https://www.cnblogs.com/galo/p/16965829.html

相关文章

  • Golang依赖管理工具:glide从入门到精通使用
    这是一个创建于 2017-07-2205:33:09 的文章,其中的信息可能已经有所发展或是发生改变。介绍不论是开发Java还是你正在学习的Golang,都会遇到依赖管理问题。Java有牛逼轰轰......
  • JAX-RS之resteasy跟spring整合
    其实,在JAX-RS标准下,jboss的resteasy跟spring结合的话,无非是如何去取得spring中的bean而已.两个方法,例子如下1比如有个接口和实现类J......
  • Spring Cloud之统一配置中心Config配置手工刷新
    实际上,配置文件也是随着应用场景变化的,如果服务已经启动并在使用过程中时需要修改其中某些配置,微服务可以直接识别并使用么?下面以SpringCloud之统一配置中心Config初......
  • flex3+blazeds+spring+hibernate整合小结
       近来flex盛行,因此这两天也借了本书看了两天,发觉作为非页面设计人员,flex还是很好的,flexbuilder很好用,拖拉就有很COOL的界面了,而且flex总的来说基本东西不难学,有编程基础......
  • 解析Spring中的ResponseBody和RequestBody
    ​​https://www.cnkirito.moe/2017/08/30/%E8%A7%A3%E6%9E%90Spring%E4%B8%AD%E7%9A%84ResponseBody%E5%92%8CRequestBody/​​​spring,restful,前后......
  • spring security 4.1两个不错功能介绍
    一转眼,springsecurity已经发布4.1了,查看了下新特性,有两个比较值得关注:1)可以在pathvariable形式的URL中进行保护了 比如有个方法:[code=......
  • java springboot 大文件分片上传处理
    ​  1 背景用户本地有一份txt或者csv文件,无论是从业务数据库导出、还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工、挖掘和共创应用的时候,首先要将本地......
  • Spring 集成提供的各种通道适配器和消息传递网关
    本节介绍Spring集成提供的各种通道适配器和消息传递网关,以支持与外部系统的基于消息的通信。每个系统,从AMQP到Zookeeper,都有自己的集成要求,本节将介绍它们。端点快速参考......
  • Spring支撑ApplicationEvent
    Spring集成提供了对入站和出站的支持,由底层Spring框架定义。有关Spring对事件和侦听器的支持的更多信息,请参阅 Spring参考手册​。​​ApplicationEvents​​您需要......
  • 未能加载文件或程序集“CefSharp.Core.dll”或它的某一个依赖项
    win10系统或win2012server系统 在使用CefSharp时CefSharp67.00:System.IO.FileNotFoundException:未能加载文件或程序集“CefSharp.Core.dll”或它的某一个依赖项......