【问题标题】:Difference between Dependency Injection and @DependsOn依赖注入和@DependsOn 的区别
【发布时间】:2020-05-06 21:26:06
【问题描述】:

我们在我们的项目中使用了 Spring,今天我发现,在我看来,这是一个奇怪的行为。在我看来,依赖注入和注释@DependsOn 在以下两种情况下应该是相同的

@Bean
public ClassA classA(){
    //code
}

@Bean
public ClassB classB(ClassA classA){
    someMethodWhichNeedsClassA()
}

和

@Bean
public ClassA classA(){
    //code
}

@Bean
@DependsOn("classA")
public ClassB classB(){
    someMethodWhichNeedsClassA()
}

看来,这两种方式并不相同。我不允许共享我的代码,但在第一种情况下,我可以访问一个列表,该列表填充了第一个 Bean,但在第二种情况下则不能。 我试图在文档或其他博客中找到一些东西,但没有成功。

有人知道这两种方式之间是否有任何区别,因为我认为这与 bean 创建的顺序有关,仅此而已。

感谢您的帮助

【问题讨论】:

  • 方法someMethodWhichNeedsClassA()中的needs是什么意思?你的意思是这个方法调用classA吗?或者你的意思是它只需要 bean classA 的初始化结果?

标签: java spring spring-boot dependency-injection dependencies


【解决方案1】:

默认情况下,Spring 管理 bean 的生命周期并安排它们的初始化顺序。这是您的第一个示例中的情况。在第二个示例中,您告诉 Spring bean B 依赖于 A。因此 spring 将在 bean B 之前创建 bean A。

@DependsOn from spring docs:

当前 bean 所依赖的 bean。指定的任何 bean 都是 保证在这个bean之前由容器创建。用过的 在 bean 没有显式依赖的情况下很少出现 另一个通过属性或构造函数参数,而是 取决于另一个 bean 初始化的副作用。

Baeldung spring DependsOn

【讨论】:

  • 您好,谢谢您的回答。在第一种情况下,ClassA bean 应该在 ClassB 之前创建,因为它在构造函数中使用,Spring 应该因为依赖注入而创建它
  • 请贴出所有相关代码。我没有看到您使用这些类中的任何一个的构造函数
  • 不允许共享代码,但是ClassB不直接依赖ClassA,而是调用了需要ClassA的方法
【解决方案2】:

如果 bean B 调用 bean A 上的任何方法(或传递给最终调用 bean A 方法的一些其他对象/方法),那么依赖注入就足够了。

Bug 有些情况下 bean B 不需要调用 bean A 上的任何方法, 但取决于bean A的初始化结果。假设bean A在其初始化期间在数据库中创建表, bean B 需要这些表才能使用。那么依赖注入就没有意义了。任何代码质量检查都会告诉你 未使用注入变量,因此不需要。 在这种情况下,您不会将 bean A 注入 B,而是声明对 bean A 的依赖。

简单来说:如果 bean B 调用 bean A,使用依赖注入。如果 bean B 只需要 bean A 的初始化结果,请使用 @DependsOn。

【讨论】:

    【解决方案3】:

    简单来说有两种情况

    1. 如果 bean 创建是按顺序进行的,spring 将从上到下开始初始化。在这种情况下,取决于 bean 需要首先列出
    2. 如果 bean 创建不按顺序并通过多个 appconfig 进行管理,在此我们可以使用 @DependsOn 注释确保依赖 bean 在使用之前被初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-09
      • 2016-08-14
      • 2015-07-15
      相关资源
      最近更新 更多