Spring解决循环注入的机制
Spring是一个大型的IOC容器,管理着应用中对象的依赖关系和生命周期。此时我们设想这么一种情况,若是Spring发生循环注入的状况,应当怎么处理?
所谓循环注入,千万不要曲解成循环调用,循环调用是指对象A中的方法调用对象B中的方法,而对象B调用对象C的方法,最后C调用A的方法,构成了一个死循环,最后肯定栈满溢出,无法解决。而循环注入则指的是对象A拥有对象B的引用,对象B拥有对象C的引用,对象C拥有对象A的引用。
一、问题状况描述
循环注入的发生有三种情形:
- 构造器注入;
- 单例bean的setter注入;
- 多例bean的setter注入;
我们在此处回顾一下单例bean的生命周期:
- 实例化单例bean;
- 注入依赖;
- 重写相应的方法能够获取bean的名字;
- 重写相应的方法能够获取beanfactory实例;
- 重写相应的方法能够在bean定义前执行;
- 重写相应的方法能够在bean定义时执行;
- 重写相应的方法在bean定义后执行;
- 重写相应的方法在bean销毁时执行;
再描述第一种情况:
当发生构造器的循环注入时,对象都依赖于对方进行实例化,也就都无法生成实例化对象,所以无法注入,大罗神仙也帮不了;
而当发生单例bean循环注入的时候,Spring提供一个提前曝光的策略,解决这个问题,后头讲解;
Spring并不会管理多例bean的生命周期,也不会提曝光多例bean,当注入一圈下来,对象C会发现对象A还在创建,所以,无法实现。
二、所谓提前曝光
在这两天查看了许许多多的博客,包括书籍《Spring源码深度解析》,无奈水平有限,无法将所有的代码看完,兜兜转转还是回到原地,本文就讲解对本文有意义的东西,并非源码。
单例bean在生成的时候,会在bean生成之前,将实例化的对象加入一个map当中,而在获取bean的时候,首先会去看这个map--earlySingleObjects,如果有就直接获取,这就是Spring单例bean的缓存,也就是所谓的提前曝光。
。。。说的实在简单,但谁让我今天生日呢,寿星最大!!!