zoukankan      html  css  js  c++  java
  • Spring循环依赖解决原理

    循环依赖问题如果不解决, 会导致栈溢出异常, 循环圈内的实例无法创建

    例如: 有3个类: A, B, C. 其中A依赖B, B依赖C, C依赖A.

    public class A {
    private B b;
    public B getB () {
    return b;
    }
    public void setB (B b) {
    this.b = b;
    }
    }
    public class B {
    private C c;
    public C getC () {
    return c;
    }
    public void setC (C c) {
    this.c = c;
    }
    }
    public class C {
    private A a;
    public A getA () {
    return a;
    }
    public void setA (A a) {
    this.a = a;
    }
    }
    Util类定义了获取它们各自实例的getBean方法, 包含两步: 1. 获取被依赖的类的实例 2. 注入到当前实例
    public class Util {
    public static A getBeanA(){
    A a = new A();
    B b = getBeanB();
    a.setB(b);
    return a;
    }
    private static B getBeanB () {
    B b = new B();
    C c = getBeanC();
    b.setC(c);
    return b;
    }
    private static C getBeanC () {
    C c = new C();
    A a = getBeanA();
    c.setA(a);
    return c;
    }
    }
    public class App {
    public static void main (String[] args) {
    A beanA = Util.getBeanA();
    }
    }
    当调用getBeanA时,就引发栈溢出异常,其根因是: 实例A时,发现需要实例B, 而实例B时发现需要实例C, 而实例C时又发现需要先实例A,可是A的实例还在等待B实例的完成, 彼此间像死锁一样缠住了.

    解决方法: 提前暴露半成品的实例 : 在被需要时, 直接将这个半成品给需要者.

    public class Util {
      // 缓存半成品的实例
    public static Map<String, Object> earlyBeanMap = new HashMap<String, Object>(3);
    public static A getBeanA(){
         // 先从半成品中拿依赖的实例, 如果没有才新建
    if(earlyBeanMap.containsKey("a")){
    return (A)earlyBeanMap.get("a");
    }
    A a = new A();
    earlyBeanMap.put("a",a);
    B b = getBeanB();
    a.setB(b);
    return a;
    }
    private static B getBeanB () {
    if(earlyBeanMap.containsKey("b")){
    return (B)beanMap.get("b");
    }
    B b = new B();
    earlyBeanMap.put("b",b);
    C c = getBeanC();
    b.setC(c);
    return b;
    }
    private static C getBeanC () {
    if(earlyBeanMap.containsKey("c")){
    return (C)earlyBeanMap.get("c");
    }
    C c = new C();
    earlyBeanMap.put("c",c);
    A a = getBeanA();
    c.setA(a);
    return c;
    }
    }
  • 相关阅读:
    犀牛书学习笔记(2):对象和数组
    犀牛书学习笔记(1):语法结构、数据类型和值、表达式和运算符
    小学了一下css hack
    git学习系列--六分之一
    稍览了一下CommonJS
    意识流_六分之一
    两升的心思系列之-----粒子的预备
    mybatis_延迟加载
    mybatis_动态SQL
    mybatis_mapper动态代理
  • 原文地址:https://www.cnblogs.com/wangxuejian/p/13944918.html
Copyright © 2011-2022 走看看