Java 在@Configuration中为spring@Bean提供依赖关系的正确方法

Java 在@Configuration中为spring@Bean提供依赖关系的正确方法,java,spring,spring-boot,Java,Spring,Spring Boot,在@Configuration类中,可以使用带有@bean注释的方法创建Springbean @Component public class Foo { } public class Bar { private Foo foo; public Bar(Foo foo) { this.foo = foo; } } @Configuration public class BarConfig { @Bean public Bar bar(Foo foo) {

在@Configuration类中,可以使用带有@bean注释的方法创建Springbean

@Component
public class Foo {
}

public class Bar {
  private Foo foo;

  public Bar(Foo foo) {
    this.foo = foo;
  }
}

@Configuration
public class BarConfig {
  @Bean
  public Bar bar(Foo foo) {
    return new Bar(foo);
  }
}
但将Foo注入BarConfig类并以这种方式使用它也可以创建Bar:

@Component
public class Foo {
}

public class Bar {
  private Foo foo;

  public Bar(Foo foo) {
    this.foo = foo;
  }
}

@Configuration
public class BarConfig {
  @Autowired
  private Foo foo;

  @Bean
  public Bar bar() {
    return new Bar(foo); // bar() without args
  }
}
从spring的角度来看,它们之间有什么不同吗?第二个不正确吗?什么东西会断裂,什么东西会因此失效


我设法发现,对于第二个,从Bar到foo没有可见的依赖关系,但它会影响任何东西吗?刷新/重新加载spring上下文将在重新创建bar时拾取foo中的更改,不是吗?

这两种自动连接之间的唯一区别是必须编写的代码量

我建议您使用第一个选项,因为它比较短


第二个选项适用于必须与
@Autowired
成对指定
@Qualifier
注释的情况,并且要注入的BEN在单独的配置中声明。

是的,在这两种情况下,您都将获得BarConfig$$EnhancerBySpringCGLIB$$,Spring将执行注入魔术。我还将使用最短版本。您还可以在方法参数上指定
@Qualifier
,无需为其创建字段注入。当然可以。但是使用单独字段的方式将突出显示依赖项。虽然在运行时,这些字段可能会表现出相同的行为,但它们不一定会这样做。在第二个配置中,
Foo
bean在启动应用程序上下文的过程中很早就被实例化。这可能导致注入非代理。这可能意味着像
@Transactional
@Async
(或任何其他与AOP相关的)之类的东西停止为该bean工作。