Spring 通过方法初始化bean

Spring beans initialization through method

我有一个关于bean创建的小问题很困扰我。

例如我有 类

public class A {
    B b;
    public A(B b) { 
        this.b = b;
    }
}
public class B {}

我想像这样给他们做豆子:

@Configuration 
public class Config {

@Bean
public B beanB() {
    return new B();
}
//version 1
@Bean
public A beanA() {
    return new A(beanB())
}
//version 2
@Bean
public A beanA(B beanB) {
    return new A(beanB)
}
}

所以,我的问题是创建 bean A 的正确方法是什么?

我认为版本 2 是正确的,因为在版本 1 中我认为 beanB 可以被调用 2 次:在创建 beanA 时以及 spring 将在其上下文中创建它。但是我找不到任何可以证明我的观点的东西。

“正确”的方法是按照 文档 的方式进行,即 @Bean 的 javadoc 显示:

@Bean Methods in @Configuration Classes

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, @Configuration classes and their factory methods must not be marked as final or private in this mode. For example:

@Configuration
public class AppConfig {

 @Bean
 public FooService fooService() {
     return new FooService(fooRepository());
 }

 @Bean
 public FooRepository fooRepository() {
     return new JdbcFooRepository(dataSource());
 }

 // ...
}

这意味着问题代码中的版本 1。

Spring 动态子类化 AppConfig,因此无论该方法被调用多少次,都只会创建一个实例,例如功能上是这样的:

public class $dynamic$ extends AppConfig {
    private FooRepository cachedFooRepository;

    @Override
    public FooRepository fooRepository() {
        if (this.cachedFooRepository == null)
            this.cachedFooRepository = super.fooRepository();
        return cachedFooRepository;
    }
}