一.下面三个缓存容器
缓存逻辑:实例化A之后,并且将beanFactory放到三级缓存中,然后执行populateBean属性注入
1.如果其他Bean没有引用这个A,那么就不会从三级缓存获取BeanFactory,和调用BeanFactory的getObject方法了,二级缓存此时就不会用到。populateBean执行完成之后就直接bean放到一级缓存中,清除其他两个缓存
2.如果有循环依赖,populateBean执行的时候就会,去三级缓存获取BeanFactory,然后调用beanFactory的 getObject方法生成代理对象,并加入到二级缓存中,属性注入完成,从二级缓存获取bean,然后加入到一级缓存并清空其他两个缓存
注意:没有存在循环依赖的话,代理对象是在初始化完成后进行的,如果有循环依赖,那么代理对象在属性注入阶段就被创建了,这样才能将代理对象注入到其他对象中。
/** Cache of singleton objects: bean name to bean instance. 一级缓存 */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** Cache of early singleton objects: bean name to bean instance. 二级缓存 */ private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); /** Cache of singleton factories: bean name to ObjectFactory. 三级缓存 */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); 复制代码
二.创建bean主要的方法是在AbstractBeanFactory.doGetBean方法关键的方法就是getSingleton这两个重载的方
1.1 从三个缓存中获取bean
@Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock //从一级缓存中获取 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //从二级缓存中获取 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { //没有获取到,加锁再重新获取 synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock //一级缓存获取 singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //二级缓存获取 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //三级缓存获取,存的是ObjectFactory ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } 复制代码
1.2 没有缓存中获取到bean的话,接下就会调用另一个重载的getSingleton方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //实例化前的校验,是否正在创建,正在创建的话会抛出异常 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //创建bean的关键入口,里面的主要的逻辑代码在AbstractAutowireCapableBeanFactory.doCreateBean方法中 //创建好bean实例之后,会接着放到三级缓存中 //addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //add方法主要逻辑将1.ObjectFactory放到三级缓存 2.移除二级缓存 //getEarlyBeanRefrence主要就是调用SmartInstantiationAwareBeanPostProcessor接口实现, //代理类就是在这一步去处理的(这个地方不会执行这个逻辑,在获取三级缓存的时候, //得到ObjectFactory对象调用getObject方法才会执行(singletonObject = singletonFactory.getObject();) //情况1.如果它的属性对象也引用了它,就出现了循环依赖。比如A、B互相依赖,当前是A,A实例化 //了,执行populateBean属性注入,执行B的实例化过程,B实例化然后执行populateBean,去获取A,从1.1的代码, //走到三级缓存,从三级缓存中获取ObjectFactory,然后getObject执行一些列代理接口,得到最终的bean,并把bean放到二级缓存 //情况2.如果对象没有循环依赖,这个在下面这个方法执行完成后还是在三级缓存中 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { //异常捕捉代码省略 .......... } if (newSingleton) { //下面四行注释是addSingleton方法copy出来的,将bean放到一级缓存中,移除三级缓存和二级缓存中的数据。上面说了两种情况,有循环依赖的话此时bean在二级缓存,没有循环依赖的话在三级缓存,这个地方没有从三级缓存拿的话,岂不是代理逻辑就没了 //this.singletonObjects.put(beanName, singletonObject); //this.singletonFactories.remove(beanName); //this.earlySingletonObjects.remove(beanName); //this.registeredSingletons.add(beanName); addSingleton(beanName, singletonObject); } } return singletonObject; } } 复制代码