spring循环依赖

AOP

AbstractAutowireCapableBeanFactory

@Override        
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
       throws BeansException {
    Object result = existingBean;
    //默认情况下开启aop后这里的对象会从6个变成7个
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        //调用每个bean初始化后的方法
       Object current = processor.postProcessAfterInitialization(result, beanName);
       if (current == null) {
          return result;
       }
       result = current;
    }
    return result;
}

添加注解@EnableAspectJAutoProxy

理论上俩个map就能解决循环依赖

但是进行AOP应该是初始化后去进行的,不符合bean生命周期的设计,而且代理对象中存在着target对象是用来存放

在当前类出现了循环依赖的情况下才需要提前进行aop

三级缓存

  1. singletonObjects:缓存经过了完整生命周期的bean
  2. earlySingletonObject:缓存未经过完整生命周期的bean,如果bean出现了循环依赖,就会吧这个暂时未经过完整生命周期的bean放入ealySingletonObject中,这个bean如果要经过AOP,那么就会把代理对象放入earlySingletonObjects中,否则就是把原始对象放入earlySingletonObjects,但不管怎么样,就是代理对象,代理对象锁代理的原始对象也是没有经过完整生命周期的,所以放入earlySingletonObjects我们就可以统一认为是未经过完整生命周期的bean。
  3. singletonFactories:缓存的是一个ObjectFatory。也就是一个lambda表达式,每个Bean的生成过程中经过实例化得到一个原始对象后,都会提前基于原始对象暴露一个lambda表达式,并保存到三级缓存中,这个lambda表达式可能用到,也可能用不到,如果当前bean没有出现循环依赖,那么这个lambda表达式没用,当前bean按照自己的生命周期正常执行,执行完后直接把bean放入SingletonObjects中,如果当前bean在依赖注入时发现了循环依赖(当前正在创建的bean被其他的bean依赖了),从三级缓存中拿到lambda表达式,并执行lambda表达式得到一个对象,并把得到的对象放入二级缓存(如果当前bean需要AOP,那么执行lambda表达式,得到就是对应的代理对象,如果无需aop),它用来记录某个原始对象是否进行过AOP了
  4. 其实还要一个缓存,就是ealyProxyReferences,它用来记录某个对象是否进行过aop了

比如A和BService出现了循环依赖

Last modification:November 17, 2023
如果觉得我的文章对你有用,请随意赞赏