①:如果没有循环依赖的话,在bean初始化完成后创建动态代理
②:如果有循环依赖,在bean实例化之后创建!
一层缓存存在的问题,里面会存着没有属性的bean 以及实例化后的bean两种,所以需要两层缓存区分开
兄弟啊,bean egg已经被注入到了其他bean:chick中。(因为我们循环依赖了),但是,注入到chick中的,是Egg类型。但是,我们这里最后对egg这个bean,进行了后置处理,生成了代理对象。那其他bean里,用原始的bean,是不是不太对啊?
只有一级
只有12
只有13
三种情况
多例的解决不了
是因为只有单例的逻辑
构造方法解决不了
是因为解决循环依赖需要实例bean 而构造方法执行时还没有实例
Setter注入的话其中可以有一两个依赖没有注入也可以获得实例,
但是构造方法注入必须全部放入才能获取实例。
—————
根据上文最后一句话可知,A先B后,A用set注入,B是构造器注入,这样的循环依赖也是可以被解决的
原因是 构造器注入在解决循环依赖的这个时候都还没有创建,相当于这个时候getbean是空的。所以只要保证不是两个对象都是空的就可以了。
————————
循环依赖的执行流程
假设 a依赖于b b依赖于a
那么a初始化的时候 会首先在三级缓存中保存,属性赋值的时候发现需要b,这时候会去找b b也会先放入三级缓存之中,属性赋值时候去找a,这时候会从一级缓存开始找a,然后找二级,然后三级找到a了,就会生成bean实例,放入到二级缓存之中,这时候可以给b填充a属性了,b创建完成后放入一级缓存之中,删除二三级缓存,b创建完成。这时候去创建a,a从一级缓存中找到b,a创建完成。
从这个流程来看确实只用1级和三级缓存就可以满足要求了。
但是如果是有aop代理的情况的话,会有点问题
如果是按照之前的流程,aop代理是初始化之后生成的,那么假设对b进行aop,那么是不是注入的时候是用的原来的b,而后面代理的是用的代理b,这前后对不上。
所以需要将代理的操作提前,如果需要代理,并且发生循环依赖的话 那么在三级缓存生成代理类,但是这时候如果只有两级缓存的话,会发现每次生成代理类都是不一样的,那不满足单例,所以二级缓存拿来存放代理类,直接从二级缓存拿就可以了。