在 Spring 中,如何在依赖类构造函数之前调用依赖类构造函数?

How the dependency class constructor is invoked before the dependent class constructor in Spring?

提问人:Neeraj-Kumar-Coder 提问时间:5/24/2023 最后编辑:Neeraj-Kumar-Coder 更新时间:5/24/2023 访问量:79

问:

我使用 Spring 框架编写了以下代码。

法典

package com.spring.core.trialDI;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@ComponentScan("com.spring.core.trialDI")
class LegendConfig {

}

@Component
class A {
    public A() {
        System.out.println("I am A constructor!");
    }
}

@Component
class B {
    A a;

    public B() {
        System.out.println("I am B constructor!");
    }

    @Autowired
    public void setA(@Qualifier("a") A a) {
        System.out.println("I am setA of B!");
        this.a = a;
    }
}

@Component
class C {
    A a;

    public C() {
        System.out.println("I am C constructor!");
    }

    @Autowired
    public void setA(@Qualifier("a") A a) {
        System.out.println("I am setA of C!");
        this.a = a;
    }
}
public class TrialTheory {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LegendConfig.class);
        B b = applicationContext.getBean(B.class);
        C c = applicationContext.getBean(C.class);
    }
}

输出

I am A constructor!
I am B constructor!
I am setA of B!
I am C constructor!
I am setA of C!

现在和方法一样,我首先创建了一个类型的 bean,因此 的构造函数必须在 setter 之前首先调用。(构造函数创建对象,其方法只能在创建对象后使用)。main()Bclass B

但是为什么在任何人之前调用 s 构造函数?幕后发生了什么?A

Java Spring 依赖注入 spring-annotations

评论

0赞 Mark Rotteveel 5/24/2023
这是一个实现工件。Spring 可能会评估 Bean B 和 C 的创建需要 Bean A,因此它会在创建和初始化 Bean B 和 Bean C 之前创建 Bean A。它可以使用不同的顺序,但我认为这将导致比此顺序复杂得多的初始化。
0赞 Mark Rotteveel 5/24/2023
此外,鉴于这些是上下文范围/单例 bean,它们将在初始化上下文时创建,而不是在请求 bean 时创建。

答:

1赞 Yevhenii Semenov 5/24/2023 #1

调用并不意味着您创建一个 Bean(如果它是一个单例 Bean,如您的示例所示)。它只给你一个已经从上下文中创建的 bean。Spring 在启动期间(在应用程序上下文创建阶段)创建单例 bean。B b = applicationContext.getBean(B.class);

您可以在此处阅读有关 spring 如何管理豆子的更多信息:https://docs.spring.io/spring-framework/reference/core/beans.html

评论

1赞 Mark Rotteveel 5/24/2023
对于默认作用域的 bean,您的答案是正确的,但是如果它是原型作用域 bean,它将在调用时创建 B。getBean
0赞 Yevhenii Semenov 5/24/2023
谢谢,这是一个很好的说明,我已经更新了我的答案