详解Spring Bean的循环依赖解决方案

 更新时间:2018年01月29日 10:21:43   作者:盲枸  
这篇文章主要介绍了详解Spring Bean的循环依赖解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

如果使用构造函数注入,则可能会创建一个无法解析的循环依赖场景。

什么是循环依赖

循环依赖其实就是循环引用,也就是两个或则两个以上的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中(这是一个典型的“先有鸡还是先有蛋”场景)。

解决方案

简明扼要的说,就是——不使用基于构造函数的依赖注入。可通过下面方式解决。

在字段上使用@Autowired注解,让Spring决定在合适的时机注入。【推荐】

基于setter方法的依赖注射取代基于构造函数的依赖注入来解决循环依赖。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • JAVA“无法验证证书。将不执行该应用程序。”提示解决办法

    JAVA“无法验证证书。将不执行该应用程序。”提示解决办法

    这篇文章主要给大家介绍了关于JAVA“无法验证证书,将不执行该应用程序”提示的解决办法,要解决Java无法验证证书的问题,可以尝试下本文的方法,需要的朋友可以参考下
    2024-03-03
  • spring boot2.0图片上传至本地或服务器并配置虚拟路径的方法

    spring boot2.0图片上传至本地或服务器并配置虚拟路径的方法

    最近写了关于图片上传至本地文件夹或服务器,上传路径到数据库,并在上传时预览图片。本文通过实例代码给大家分享spring boot2.0图片上传至本地或服务器并配置虚拟路径的方法,需要的朋友参考下
    2018-12-12
  • Java基础之重载(Overload)与重写(Override)详解

    Java基础之重载(Overload)与重写(Override)详解

    这篇文章主要介绍了Java基础之重载(Overload)与重写(Override)详解,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • Java使用keySet方法获取Map集合中的元素

    Java使用keySet方法获取Map集合中的元素

    这篇文章主要为大家详细介绍了Java使用keySet方法获取Map集合中的元素,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Nebula Graph介绍和SpringBoot环境连接和查询操作

    Nebula Graph介绍和SpringBoot环境连接和查询操作

    Nebula Graph 是一款开源的、分布式的、易扩展的原生图数据库,能够承载包含数千亿个点和数万亿条边的超大规模数据集,并且提供毫秒级查询,这篇文章主要介绍了Nebula Graph介绍和SpringBoot环境连接和查询,需要的朋友可以参考下
    2022-10-10
  • 详谈java线程与线程、进程与进程间通信

    详谈java线程与线程、进程与进程间通信

    下面小编就为大家带来一篇详谈java线程与线程、进程与进程间通信。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Springboot集成JSR303参数校验的方法实现

    Springboot集成JSR303参数校验的方法实现

    这篇文章主要介绍了Springboot集成JSR303参数校验的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • java poi 读取单元格null或者空字符串方式

    java poi 读取单元格null或者空字符串方式

    这篇文章主要介绍了java poi 读取单元格null或者空字符串方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 图解Java经典算法插入排序的原理与实现

    图解Java经典算法插入排序的原理与实现

    插入排序的算法描述是一种简单直观的排序算法。其原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。本文将用Java语言实现插入排序算法并进行可视化,感兴趣的可以了解一下
    2022-09-09
  • Java超详细分析垃圾回收机制

    Java超详细分析垃圾回收机制

    一个运行中的程序, 产生的对象是大量的, 如果对象不被继续使用, 就会成为垃圾, 最后越堆越多, 最后占满内存, 所以我们要对这些垃圾进行回收,保持程序的正常运行
    2022-05-05

最新评论