什么是循环依赖
spring在创建bean的时候,aBean中有一个需要注入的bBean,bBean中有一个需要注入的aBean的时候,aBean就与bBean发生了循环依赖
一级缓存
singletonObjects:实际上是一个ConcurrentHashMap,用来存储已经创建好的bean信息,开发用刀的bean就是这里取到的
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
二级缓存
earlySingletonObjects:实际上是一个ConcurrentHashMap,用来存储出现循环依赖时提前产生的对象
例如:创建aBean时注入bBean,但是bBean又需要aBean,这个时候就需要在二级缓存中存上aBean对象。
为什么不直接创建aBean的对象而是缓存起来呢?原因就是因为单例,要确保bean只有一个,如果每次都重新创建那么bean就是多个了
例如:aBean中有bBean,cBean,但是bBean,cBean都需要aBean。这个时候如果不把aBean存到二级缓存,而是每次创建,那么bBean,cBean中的aBean就是两个不一样的bean了
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
三级缓存
singletonFactories:实际上是一个hashMap,用来存储创建对象的lambda表达式,当注入bean的时候发现一级缓存和二级缓存都没有时,调用lambda表达式创建对象,创建对象之后放入到二级缓存中
为什么使用lambda表达式,而不是直接存对象呢?原因就是为了处理AOP的问题,如果这个对象有AOP的需求那么需要的对象就是代理对象而不是普通对象。为了保证三级缓存中拿到的跟最终放到一级缓存中的是同一个对象,所以三级缓存存的是表达式,只有使用的时候才通过表达式产生一个对象,当然具体是代理对象还是普通对象也是在表达式中判断的
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);