1.Spring解决循环依赖

什么是循环依赖:比如A引用B,B引用C,C引用A,它们最终形成一个依赖环。

循环依赖有两种
  1、构造器循环依赖

    构造器注入导致的循环依赖,Spring是无法解决的,只能抛出BeanCurrentlyInCreationException异常。因为构造器注入时的参数需要依赖bean的实例。所以无法解决循环依赖的问题。

    如在创建A的实例时,发现依赖B,那将去创建B的实例,又发现依赖C,则又去创建C,最终在创建C的时候发现依赖A,从而形成一个环,没办法创建。

    Spring容器每一个正在创建的bean标识符放在一个“当前创建bean池”中,这个池是一个set集合

private final Set<String> singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet());

    bean标识符将一直保持在这个池中,因此如果bean创建过程中发现自己已经在当前创建bean池中时,将抛出BeanCurrentlyInCreationException异常表示循环依赖。而对于创建完毕的bean将从“当前创建bean”池中清除掉。

    

  2、setter循环依赖

    表示通过setter注入方式构成的循环依赖。对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器创建实例但未完成其他步骤如setter注入的bean来完成的。提前暴露一个

    单例工厂方法,从而使其他bean能引用该bean。

    而且只能解决单例作用域的bean循环依赖。

    步骤:

    1、Spring容器创建单例A bean,首先通过无参构造器创建bean,并暴露一个ObjectFactory返回一个在创建中的bean,并将A标识符放在当前创建bean池中。然后通过setter方式注入

    依赖B

    2、Spring容器创建单例B bean,首先通过无参构造器创建bean,并暴露一个ObjectFactory返回一个在创建中的bean,并将B标识符放在当前创建bean池中。然后通过setter方式注入

    依赖C

    3、Spring容器创建单例C bean,首先通过无参构造器创建bean,并暴露一个ObjectFactory返回一个正在创建中的bean,并将C标识符放在当前创建bean池中。然后setter方式

    注入A,进行注入A时由于提前暴露了ObjectFactory工厂,所以使用它返回提前暴露一个创建中的bean。

    4.然后再依次完成setter注入C完成B创建,依赖注入B完成A创建。

    prototype范围的依赖处理:spring也无法完成依赖注入,因为Spring容器不进行缓存prototype作用域的bean,因此无法暴露一个创建中的bean。(单例范围下是通过放入缓存中的ObjectFactory来创建实例)

    缓存objectFactory是将ObjectFactory放入map中

private final Map<String, ObjectFactory> singletonFactories = new HashMap();

this.singletonFactories.put(beanName, singletonFactory);

this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
// 在此完成aop动态织入
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});

   aop将advice动态织入bean中也是在将创建bean的工厂放在单例工厂集合中时织入的。

  常规bean的创建是在AbstratAutowireCapableBeanFactory的doCreateBean方法中创建的。
  创建完成的bean,如果配置了destory-method则放在LinkHashMap中,便于在销毁时调用。
private final Map<String, Object> disposableBeans = new LinkedHashMap();
 

Spring解决循环依赖的更多相关文章

  1. 浅谈Spring解决循环依赖的三种方式

    引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...

  2. Spring解决循环依赖,你真的懂了吗?

    导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构 ...

  3. 曹工说Spring Boot源码(29)-- Spring 解决循环依赖为什么使用三级缓存,而不是二级缓存

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  4. 建议收藏!利用Spring解决循环依赖,深入源码给你讲明白!

    前置知识 只有单例模式下的bean会通过三级缓存提前暴露来解决循环依赖的问题.而非单例的bean每次获取都会重新创建,并不会放入三级缓存,所以多实例的bean循环依赖问题不能解决. 首先需要明白处于各 ...

  5. Spring如何解决循环依赖问题

    目录 1. 什么是循环依赖? 2. 怎么检测是否存在循环依赖 3. Spring怎么解决循环依赖 本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可 ...

  6. 一张图彻底理解Spring如何解决循环依赖!!

    写在前面 最近,在看Spring源码,看到Spring解决循环依赖问题的源码时,不得不说,源码写的太烂了.像Spring这种顶级的项目源码,竟然存在着这种xxx的代码.看了几次都有点头大,相信很多小伙 ...

  7. 彻底理解Spring如何解决循环依赖

    Spring bean生命周期 可以简化为以下5步. 1.构建BeanDefinition 2.实例化 Instantiation 3.属性赋值 Populate 4.初始化 Initializati ...

  8. 【Spring】 Spring如何解决循环依赖的问题?

    https://mp.weixin.qq.com/s/FtbzTMxHgzL0G1R2pSlh-A 通常来说,如果问Spring内部如何解决循环依赖,一定是单默认的单例Bean中,属性互相引用的场景. ...

  9. 听说你还不知道Spring是如何解决循环依赖问题的?

    Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题. 其实笔者本人对这类框架源码题还是持一定的怀疑态度的. 如果笔者作为面试官,可能会问一些诸如"如果注入的属性为null, ...

随机推荐

  1. 01 spring security入门篇

    1. 环境搭建 使用SpringBoot搭建开发环境,只需在pom.xml添加如下依赖即可. <?xml version="1.0" encoding="UTF-8 ...

  2. java 标准输入输出流,打印流,数据流

    1 package stream; import static org.junit.Assert.assertNotNull; import java.io.BufferedReader; impor ...

  3. git修改commiter date

    GIT: change commit date to author date git filter-branch --env-filter 'export GIT_COMMITTER_DATE=&qu ...

  4. ajax请求controller出现中文乱码

    ajax请求controller出现中文乱码 解决方法:在 @RequestMapping 中加上  produces = {"application/json;charset=UTF-8& ...

  5. mootools使用Request.send()数据时刷新整个页面

    今天使用mootools做ajax登录时使用Request().send()数据时老是刷新整个页面,换成Requesr.JSON()也不行,弄了好长时间,很郁闷啊,最后终于发现onSuccess:fu ...

  6. Windows server 2016远程桌面登录和修改3389端口

  7. C# 与 C++ 互操作(C# 调用 C++ 的动态链接库)

    1.新建 C++ 动态链接库项目 CPlus.cpp: #include "stdafx.h" extern "C" __declspec(dllexport) ...

  8. C#设计模式V2(1)——单例模式

    出自:https://www.cnblogs.com/zhili/p/SingletonPatterm.html 一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计 ...

  9. 前序遍历+中序遍历 --> 后序遍历 (二叉树)

  10. 案例:使用xml存储数据

    HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...