近期重新阅读Spring源码,总结了Spring Bean的加载过程如下:
Spring Bean的加载过程
Spring Bean的创建过程
Spring Bean循环依赖解决方式
Spring中将循环依赖分成三种情况,
- 构造器循环依赖:无法解决,抛出BeanCurrentlyInCreationException异常。
- setter循环依赖:只能解决单例Bean的循环依赖。
- prototype范围的依赖处理:无法解决,抛出BeanCurrentlyInCreationException异常。
其中用于解决单例Bean的循环依赖的重要属性如下所示:
// DefaultSingletonBeanRegistry类中
/** 单例对象的缓存map,存放实例化完成的bean实例对象:bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 单例对象工厂的缓存map,用于解决循环依赖(包括AOP),存放:bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 用来保存当前所有已注册的Bean */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** 正在创建中的bean名称集合 */
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
解决过程更多参考源码理解,这里给出大致流程和每个节点缓存map中的值:
欢迎关注微信公众号:方辰的博客