代码之家  ›  专栏  ›  技术社区  ›  Antoniossss

为什么Spring对待构造函数注入和setter/field注入不同?

  •  1
  • Antoniossss  · 技术社区  · 7 年前

    我在项目中遇到了一个循环依赖的小问题,发现使用 @Autowired 在字段/设置器上,可以修复而不是使用 @自动售货机 在构造函数上。这种行为的结论是,在字段/设置器注入的情况下,Spring注入代理,在构造函数注入的情况下,Spring注入实际bean。

    问题: 这背后的原因是什么?为什么注入不同的实体?

    考虑简单的代码段:

        @Component
        public static class A{
            @Autowired B b;
            @Autowired C c;
        }
        @Component
        public static class B{
            @Autowired B b;
            @Autowired C c;
    //      public B(C c,B b) { // this would cause circular dep problem
    //          this.c=c;
    //      }
        }
        @Component
        public static class C{
            @Autowired A a;
            @Autowired B b;
        }
    

    我想到的一个想法是,通过构造函数注入,您可以立即使用注入的实体,因此作为一个预先定义的已初始化bean被注入而不是代理,但是另一方面,在setter方法的情况下,我也可以这样做,这样接缝就无效了。

    1 回复  |  直到 7 年前
        1
  •  1
  •   marok    7 年前

    所以当您使用构造函数注入时,所有在构造函数中使用的bean都必须在前面创建。如果您有循环依赖项,那么就不能创建它们,因为这个循环依赖项和Spring-Throw异常。

    当您使用setter/field injection时,注入的元素是在bean创建之后设置的,因此允许使用cirular依赖项。

    顺便说一句,如果您有循环依赖关系,请尝试重新设计应用程序,因为您的代码将很难维护。这是首选构造函数注入的原因之一。