• Spring中的循环依赖


    循环依赖

    在使用Spring时,如果主要采用基于构造器的依赖注入方式,则可能会遇到循环依赖的情况,简而言之就是Bean A的构造器依赖于Bean BBean B的构造器又依赖于Bean A。在这种情况下Spring会在编译时抛出BeanCurrentlyInCreationException

    Class A

    @Component
    public class ClassA {
        private ClassB classB;
    
        @Autowired
        public ClassA(ClassB classB) {
            this.classB = classB;
        }
    
        public void printClass() {
            System.out.println("Class A = " + this);
            System.out.println("Class B = " + classB);
        }
    }
    

    Class B

    @Component
    public class ClassB {
        private ClassA classA;
    
        @Autowired
        public ClassB(ClassA classA) {
            this.classA = classA;
        }
    
        public void printClass() {
            System.out.println("Class A = " + classA);
            System.out.println("Class B = " + this);
        }
    }
    

    测试

    @ContextConfiguration(classes = {ClassA.class, ClassB.class})
    @RunWith(SpringRunner.class)
    public class MyTest {
        @Autowired
        private ClassA classA;
        @Autowired
        private ClassB classB;
    
        @Test
        public void name() {
            classA.printClass();
            classB.printClass();
        }
    }
    

    原因

    这时候运行测试就会发现抛出了BeanCurrentlyInCreationException异常。产生这种情况的原因是,Spring在创建Bean时,会首先实例化对象,然后再注入依赖。假设Spring首先创建Class A,那么就会发现在构造器里有Class B的依赖,所以就会转去创建Class B,又在Class B的构造器里发现了对Class A的依赖,而此时Class A是还未初始化完的,因此又会转去创建Class A,这样就陷入了死循环。

    解决方法

    换成基于setter的依赖注入即可解决这个问题。因为基于setter的依赖注入会首先调用默认构造函数来实例化对象,然后再调用setter实现依赖注入。这样在对象实例化的阶段就没有了任何依赖,因此Class A实例化完成后再调用Class BClass B实例化完成后开始设值,而这时Class A已经是实例化完成了的,所以可以成功引用到Class A

  • 相关阅读:
    Ant.OutputIsUnreadableCode
    Android.HowToDesignPluginArchitectureInAndroidApp
    Java.FamousBlogs
    Java.WeakReference-SoftReference-PhantomReference
    DataStructure.BloomFilter
    Android.HowToDefineCustomView
    Android.Study.Question
    Android.PublishApplication
    Android.Libraries
    Site.AboutHardware
  • 原文地址:https://www.cnblogs.com/xz816111/p/9048908.html
Copyright © 2020-2023  润新知