Spring:对constructor \ setter注入的循环依赖

时间:2014-01-17 09:28:02

标签: java spring dependency-injection

我读过circular dependencies是由setter注射引起的。所以我试着自己检查一下。而且我似乎只能通过circular dependency注入重现constructor(请参阅下面的代码)。

所以问题:

  1. 我可以使用circular dependency注射来完成setter吗?
  2. 如何解决以下代码中的circular dependencies

    public class AConstr {
    
      private final BConstr b;
    
      public AConstr(BConstr bConstr) {
        System.out.println("AConstructor:: constructor");
        this.b = bConstr;
      }
    }
    
    public class BConstr {
    
      private final AConstr a;
    
      public BConstr(AConstr aConstr) {
        System.out.println("BConstructor:: constructor");
        this.a = aConstr;
      }
    }
    
    <bean id="aConstr" class="pack.bean.AConstr">
       <constructor-arg ref="bConstr"/>
    </bean>
    <bean id="bConstr" class="pack.bean.BConstr">
       <constructor-arg ref="aConstr"/>
    </bean>
    

3 个答案:

答案 0 :(得分:1)

请参阅循环依赖性仅由构造函数注入引起。在您的示例中,您可以使用setter而不是构造函数。

  1. 如果是构造函数注入,它将在构造函数中说AConstr,并且在执行BConstr之前它将再次注意AConstr转到BConstr并尝试创建BConstr的对象。

  2. 现在它将控制将来到BConstr的构造函数,然后它会找到依赖项'AConstr'。这将创造永无止境的连锁店。

  3. 在Setter注入期间为了注入一个对象,它将创建该对象。如果你有二次注射,那就没问题了。

  4. 所以当你打电话

     context.getBean("aConstr");
    
  5. 首先创建一个aConstr对象,然后调用setter注入,进一步将依赖注入为bConstr

答案 1 :(得分:1)

我知道答案有点迟,但迟到总比没有好:

如果您仔细阅读该文章,您会发现可能您的设计错误: http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/

Setter注入只会隐藏它。

答案 2 :(得分:1)

有两种方法可以使用Spring FooController BarController + + | | + + FooService<-------->BarService + + | | + + FooJpaRepository BarJpaRepository + + | | + + FooEntity BarEntity 注入依赖项: field 构造函数

如果您有以下图层:

  • RestController
  • 服务
  • JpaRepository
  • 实体

使用以下绑定:

  • 1 RestController 仅绑定到关联的服务
  • 1 服务仅使用关联的 JpaRepositories 来管理关联的实体
  • 要与服务功能范围之外的实体进行交互,服务将使用其他服务
@Autowired

因此,2 Services 可以相互依赖(直接或不相关)是正常的,这就是为什么你可以打破循环依赖:

  • 字段上使用@Lazy,而不是在您的某个服务中使用构造函数
  • 或者只是在构造函数参数之前添加public ArrayList<Song> arrayOfSongs; public SongsAdapter adapter;

这是Spring建议的内容:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-dependencies

另一方面,应该通过构造函数服务(或直接 JpaRepository )注入 RestControllers >。在这种情况下,循环依赖将是架构问题。