zoukankan      html  css  js  c++  java
  • spring循环依赖为什么要三级缓存

    先记想法后续补充
    要理解为啥要三级缓存,我们先假设二级缓存能不能完成功能。
    只用两级缓存可以解决循环依赖问题,但仅仅限于没有代理的情况。

    一旦涉及到代理,就有个流程顺序问题了。
    常规getbean操作流程是先实例化-放入三级缓存一个factorybean-注入-执行初始化方法(其中执行了beanpostprocessor,这个过程可以修改bean,包括修改类型等等)-生成代理-存到一级缓存-删除三级缓存。

    这个时候如果只有两级缓存那么意味着为了解决循环依赖问题时必须在二级缓存中就放入A的代理类,而不是factorybean。这样才能在A注入B时,B直接注入A的代理类。
    这时流程就变成了实例化-生成代理-放入二级缓存-注入-执行初始化方法(其中执行了beanpostprocessor,这个过程可以修改bean,包括修改类型等等)-存到一级缓存-删除二级缓存。
    这个时候流程就出现了问题,因为生成代理后续的操作均需要A目标类完成,比如注入,执行初始化方法等,特别是beanpostprocessor甚至还可能修改A目标,这样之前生成的代理就是无用功,违背了bean创建流程。

    总结下,三级缓存设计不能光看循环依赖这种场景,要结合普通创建场景来看,绝大部分场景是没有循环依赖的,所以是需要将代理放到最后来实现的,只是为了解决循环依赖这种特殊情况才不得不把代理类提前生成,而又要兼顾普通场景,所以要三级缓存来解决。
    所以像循环依赖这种场景,如果beanpostprocessor中替换了Abean成Cbean,B中注入的是Abean,那么是会报错的,因为上下文AbeanName存在了2个实例,一个A一个C。假设不是循环依赖则不会报错,而是将C放入上下文。

  • 相关阅读:
    finally 到底是什么时候执行的问题
    转发与重定向
    java中的常量池
    数据库优化之设置fetchSize
    java集合去重和排序
    jdbc连接数据库
    重写和重载的区别
    <? extends E>和<? super E> 的意义和区别
    入栈和出栈规律
    JAVA中poi操作excel合并单元格的技巧,以及easypoi,注解@Excel的操作
  • 原文地址:https://www.cnblogs.com/wish5714/p/15041882.html
Copyright © 2011-2022 走看看