java 循环依赖_Java详解之Spring Bean的循环依赖解决方案
如果使用构造函数注入,则可能会创建一个无法解析的循环依赖场景。
1. 什么是循环依赖
循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图:
注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
Spring中循环依赖场景有:
(1)构造器的循环依赖
(2)field属性的循环依赖。
怎么检测是否存在循环依赖
检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。
下面是我所遇到的情况,代码结构如下:
SpringSecurity 配置类:
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
private final UserDetailsService userDetailsService;
/**
* 通过配置类构造函数注入 UserDetailsService
*/
@Autowired
public BrowserSecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
/**
* 在配置类中声明 加密编码器
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
... ...
}
UserDetailsService 类:
@Component
public class MyUserDetailService implements UserDetailsService{
private final PasswordEncoder passwordEncoder;
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 通过构造函数注入 PasswordEncoder
*/
@Autowired
public MyUserDetailService(PasswordEncoder passwordEncoder){
this.passwordEncoder = passwordEncoder;
}
... ...
}
运行之后,Spring抛出了如下错误信息:
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| browserSecurityConfig defined in file [D:\CODE\Java\IdeaProjects\mango-security\mango-security-browser\target\classes\stu\mango\security\browser\BrowserSecurityConfig.class]
↑ ↓
| myUserDetailService defined in file [D:\CODE\Java\IdeaProjects\mango-security\mango-security-browser\target\classes\stu\mango\security\browser\MyUserDetailService.class]
└─────┘
该例中,BrowserSecurityConfig 通过构造函数注入 UserDetailsService实例,而 UserDetailsService由通过构造函数注入在BrowserSecurityConfig 中声明的PasswordEncoder。
总结来说,Spring Bean的循环依赖是指,类A需要通过构造函数注入的类B的实例(或者B中声明的Bean),而类B需要通过构造函数注入的类A的实例(或者A中声明的Bean)。如果将类A和类B的bean配置为相互注入,则Spring IoC容器会在运行时检测到此循环引用,并引发一个BeanCurrentlyInCreationException。与典型情况(没有循环依赖)不同,bean A和bean B之间的循环依赖关系迫使其中一个bean在被完全初始化之前被注入到另一个bean中(这是一个典型的“先有鸡还是先有蛋”场景)。
2. 解决方案
简明扼要的说,就是――不使用基于构造函数的依赖注入。可通过下面方式解决。
在字段上使用@Autowired注解,让Spring决定在合适的时机注入。【推荐】
用基于setter方法的依赖注射取代基于构造函数的依赖注入来解决循环依赖。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
java 循环依赖_Java详解之Spring Bean的循环依赖解决方案相关推荐
- java webmethod 参数_java详解Spring接收web请求参数的方式
本篇文章给大家带来的内容是java详解Spring接收web请求参数的方式 .有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 1 查询参数 请求格式:url?参数1=值1&参 ...
- java开发流程图_Java 详解 JVM 工作原理和流程
作为一名Java使用者,掌握JVM的体系结构也是必须的. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java ...
- Spring三级缓存解决循环依赖问题详解
spring三级缓存解决循环依赖问题详解 前言 这段时间阅读了spring IOC部分的源码.在学习过程中,自己有遇到过很多很问题,在上网查阅资料的时候,发现很难找到一份比较全面的解答.现在自己刚学习 ...
- java list jstl_详解javaweb中jstl如何循环List中的Map数据_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 详解javaweb中jstl如何循环List中的Map数据 第一种方式: 1:后台代码(测试) List> lis ...
- Spring 依赖注入详解
一.IOC 依赖注入 1.什么是Spring的依赖注入 依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释.这概念是说你不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和服 ...
- java反射机制深入详解_Java反射机制深入详解
原标题:Java反射机制深入详解 一.概念 反射就是把Java的各种成分映射成相应的Java类. Class类的构造方法是private,由JVM创建. 反射是java语言的一个特性,它允程序在运行时 ...
- java 8 新功能详解_Java 8和Java 14之间的新功能
java 8 新功能详解 从版本9开始,Java每6个月就有一次新功能,因此很难跟踪这些新更改. 互联网上的大多数信息都描述了最近2个Java版本之间的变化. 但是,如果您的情况与我相似,则说明您使用 ...
- java 8 新功能详解_Java 8的8个新功能
java 8 新功能详解 注意:确保还检查了我们的详细教程Java 8 Features – ULTIMATE Guide . Jdk 1.8(又名Java 8)今天发布,这意味着它的通用发布版本已经 ...
- Java并发之AQS详解(文章里包含了两片文章结合着看后边文章不清楚,请看原文)
AQS全称抽象队列同步器(AbstractQuenedSynchronizer),它是一个可以用来实现线程同步的基础框架.当然,它不是我们理解的Spring这种框架,它是一个类,类名就是A ...
- Java编程配置思路详解
Java编程配置思路详解 SpringBoot虽然提供了很多优秀的starter帮助我们快速开发,可实际生产环境的特殊性,我们依然需要对默认整合配置做自定义操作,提高程序的可控性,虽然你配的不一定比官 ...
最新文章
- 数据库设计的10个最佳实践
- 论文笔记:Forecasting at Scale(Prophet)
- html 如何让div刷新页面,页面刷新.html
- python文件字符串操作
- 频繁刷新页面websocket会报错_代码优化:Node+WebSocket+Vue聊天室
- MySQL(17)-----数值函数
- 如果你想专升本那就一定要看的文学常识完整版(三)
- Rational Rose安装使用教程
- itest听力答案2020_itest大学英语测试答案2019
- jflash烧录教程_Jflash烧录(windows)原理分析
- 如何使用YouTube视频管理器
- 解决Android 拍照图片被旋转问题
- php 打开模态框,模态框打开页面
- 深度学习·理论篇(2023版)·第001篇快速了解人工智能与Pytorch:机器/表示/深度学习定义+端到端的学习+神经网络在计算机视觉应用+深度学习的技术蓝图
- SpringBoot与RocketMQ客户端集成原理解读与示例
- cad转dxf格式文件太大,将CAD图纸文件进行转换成低版本DXF格式如何进行?
- Ubuntu 下Android开发环境搭建
- Java设计模式系列3-----装饰模式,策略模式,观察者模式
- 类中无错误显示,但类名出线红色波浪线
- 操作系统——进程的三态模型
热门文章
- PhotoShop中蒙版介绍
- AVR单片机ATMEGA16编译软件ICCAVR的使用技巧与应用示例
- DRAM Devices Organization
- Rootkit Hacking Technology Defence Strategy Research
- matlab 创建网格图和曲面图
- C1. Skyscrapers (从easy到hard)
- matlab绘制三维图形,Matlab 应用之绘制三维图形(基础篇)(组图)
- 安全模式解除android,手机安全模式怎么解除
- 麒麟v10服务器系统搭建本地源
- 服务器能不能清理系统垃圾,在服务器上如何清理垃圾