我是 javapub,一名 Markdown 程序员从‍,八股文种子选手。

面试官: 小伙子,听说你对 Spring 循环依靠比较熟悉,是真的吗?

提名人: 王哥,不敢说很熟悉,但有必定了解,请王哥考考我。

面试官: 那好,首要简单说一下,什么是 Spring 循环依靠?

提名人: Spring 循环依靠指的是 BeanA 依靠 BeanB,而 BeanB 也直接或间接依靠 BeanA,两者之间形成依靠循环。这会导致 Bean 无法正常实例化。

面试官: circular dependencies,确实是这样。Spring Bean 的循环依靠有哪些场景?

提名人: 首要有三种场景:

  1. 结构器循环依靠:BeanA 的结构器注入 BeanB,BeanB 的结构器又注入 BeanA。
  2. Setter 循环依靠:BeanA 在 setter 办法中注入 BeanB,BeanB 的 setter 办法又注入 BeanA。
  3. 署理循环依靠:BeanA 依靠 BeanB 的署理方针,BeanB 依靠 BeanA 的署理方针。

面试官: 那 Spring 是怎么解决循环依靠问题的呢?

提名人: Spring 选用提早露出方针的办法解决循环依靠,首要通过 AOP 功能和 SmartInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 办法实现。

  1. 对署理循环依靠,Spring 会首要创立方针方针,然后再创立署理方针。
  2. 对 Setter 循环依靠,Spring 会在方针创立完结后,提早将方针注入到 BeanFactory 中。然后在注入依靠时,直接从 BeanFactory 中获取现已提早实例化的方针。
//AbstractAutowireCapableBeanFactory#doCreateBean
    ...
     // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    Object bean = resolveBeforeInstantiation(beanName, mbd);
    if (bean != null) {
        return bean;
    }
    ...  
    // Allow post-processors to modify the merged bean definition.
    bean = applyBeanPostProcessorsAfterInstantiation(bean, beanName);
    ... 
  1. 对结构器循环依靠,Spring 在实例化方针后,会提早露出一个 ObjectFactory,再从 ObjectFactory 中获取方针方针完结依靠注入。

面试官: 那么,Spring 循环依靠会带来什么问题?

提名人: Spring 循环依靠首要会带来以下问题:

  1. 损坏 Bean 的单例性。因为循环依靠导致一个 Bean 被实例化多次,损坏了 Spring 容器中 Bean 的唯一性。
  2. 容器无法正常完毕注入过程。循环依靠会导致 Bean 无法彻底实例化,一直在循环注入过程中,无法完毕。
  3. 降低程序的可读性和保护性。循环依靠关系使得程序难以了解,也难以保护。

面试官: 那么,怎么防止 Spring 循环依靠呢?

提名人: 首要有以下几种办法能够防止 Spring 循环依靠:

  1. 编程办法防止。在 Bean 中供给 set 办法,但不在结构器中注入依靠。这样只有在 Bean 彻底实例化后,才会注入依靠方针。
  2. 结构器注入防止。只使用结构器注入,不必 Setter 办法注入。因为结构器是在 Bean 实例化阶段完结的,防止了循环依靠。
  3. 防止过于提早露出 Bean。假如一个 Bean 不需要频繁使用,不要将其设置为 Singleton,推迟其实例化时刻。
  4. 分模块防止。将循环依靠的 Bean 拆分到不同的模块中,模块间选用接口隔离,防止循环依靠。
  5. 选用重构手法。假如上述办法都不可行,那么需要通过重构来防止循环依靠。比如拆分过于庞大的 Bean 为多个小 Bean 等。

面试官: 不错,总结得很全面。看来你对 Spring 循环依靠仍是比较明晰的,加油!

提名人: 谢谢 王哥 的提问,让我对 Spring 循环依靠有了更深化的知道。我会持续努力学习的!

《面试1v1》Spring循环依赖

最近我在更新《面试1v1》系列文章,首要以场景化的办法,讲解咱们在面试中遇到的问题,致力于让每一位工程师拿到自己心仪的offer,感兴趣能够重视JavaPub追更!


《面试1v1》 连载中…


目录合集:

Gitee:https://gitee.com/rodert/JavaPub

GitHub:https://github.com/Rodert/JavaPub

javapub.net.cn