getbean()方法是否共享bean的不同实例?

huangapple go评论71阅读模式
英文:

Does getbean() method share the beans for different instances of the bean?

问题

I have written a program to resolve circular dependencies using setter-based dependency injection. But the output is somewhat confusing.

CODE

package com.spring.core.di;

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.di")
class CoolAppConfig {

}

@Component
class DependencyA {
    DependencyB dependencyB;

    public DependencyA() {
        System.out.println("I am constructor of Dependency A");
    }
    
    @Autowired
    public void setDependencyB(@Qualifier("dependencyB") DependencyB dependencyB) {
        System.out.println("I am setDependencyB !");
        this.dependencyB = dependencyB;
    }

    public void say() {
        this.dependencyB.who();
    }

    public void who() {
        System.out.println("I am Dependency A");
    }
}

@Component
class DependencyB {
    DependencyA dependencyA;

    public DependencyB() {
        System.out.println("I am constructor of Dependency B");
    }

    @Autowired
    public void setDependencyA(@Qualifier("dependencyA") DependencyA dependencyA) {
        System.out.println("I am setDependencyA !");
        this.dependencyA = dependencyA;
    }

    public void say() {
        this.dependencyA.who();
    }

    public void who() {
        System.out.println("I am dependency B");
    }
}

public class CircularDependencyIssue {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CoolAppConfig.class);

        DependencyA dependencyA = applicationContext.getBean(DependencyA.class);
        DependencyB dependencyB = applicationContext.getBean(DependencyB.class);

        dependencyA.say();
        dependencyB.say();
    }
}

OUTPUT

I am constructor of Dependency A
I am constructor of Dependency B
I am setDependencyA !
I am setDependencyB !
I am dependency B
I am Dependency A

In the main method, I have created an instance of DependencyB. Now my question is, when we are creating DependencyA bean first, it will output "I am constructor of Dependency A" and after resolving DependencyB, it will also output "I am constructor of Dependency B."

Now when we are creating the bean of DependencyB, why is the constructor of Dependency B not called again? I mean, "I am constructor of Dependency B" should be printed twice in the output, but it is present only once.

Does that mean the beans/objects are shared between dependencyB and the object created while resolving the dependency of dependencyA?

How does this flow work?

英文:

I have written a program to resolve circular dependencies using setter-based dependency injection. But the output is somewhat confusing.

CODE

package com.spring.core.di;
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.di")
class CoolAppConfig {
}
@Component
class DependencyA {
DependencyB dependencyB;
public DependencyA() {
System.out.println("I am constructor of Dependency A");
}
@Autowired
public void setDependencyB(@Qualifier("dependencyB") DependencyB dependencyB) {
System.out.println("I am setDependencyB !");
this.dependencyB = dependencyB;
}
public void say() {
this.dependencyB.who();
}
public void who() {
System.out.println("I am Dependency A");
}
}
@Component
class DependencyB {
DependencyA dependencyA;
public DependencyB() {
System.out.println("I am constructor of Dependency B");
}
@Autowired
public void setDependencyA(@Qualifier("dependencyA") DependencyA dependencyA) {
System.out.println("I am setDependencyA !");
this.dependencyA = dependencyA;
}
public void say() {
this.dependencyA.who();
}
public void who() {
System.out.println("I am dependency B");
}
}
public class CircularDependencyIssue {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(CoolAppConfig.class);
DependencyA dependencyA = applicationContext.getBean(DependencyA.class);
DependencyB dependencyB = applicationContext.getBean(DependencyB.class);
dependencyA.say();
dependencyB.say();
}
}

OUTPUT

I am constructor of Dependency A
I am constructor of Dependency B
I am setDependencyA !
I am setDependencyB !
I am dependency B
I am Dependency A

In the main method I have created an instance of DependencyB. Now my question is, When we are creating DependencyA bean first, it will output "I am constructor of Dependency A" and after resolving the DependencyB will also output "I am constructor of Dependency B".

Now when we are creating the bean of DependencyB, why the constructor of Dependency B not called? I mean "I am constructor of Dependency B", this should be printed twice in the output, but is present only once.

Does that mean, the beans/objects are shared among dependencyB and the object created while resolving dependency of dependencyA?

How does this flow working?

答案1

得分: 1

默认的Bean范围是Singleton,因此每个类只会存在一个由Spring管理的实例。

您可以尝试在其中一个实例上添加@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)以查看您期望的行为。

有关更多信息,可以参考Baeldung页面:https://www.baeldung.com/spring-bean-scopes

英文:

The default Bean scope is Singleton, so only a single spring-managed instance will live for each class.

You could try adding a @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) to one of your instances to see your expected behavior.

For more information, this Baeldung page may be helpful: https://www.baeldung.com/spring-bean-scopes

答案2

得分: 0

默认范围是单例,因此只会创建一个对象,因此构造函数仅调用一次。
Bean的生命周期:
https://howtodoinjava.com/spring-core/spring-bean-life-cycle/
实现BeanFactoryPostProcessors、BeanPostProcessor以检查bean的创建时间。

英文:

The default scope is a Singleton so only one object will be created hence, the constructor was called only once.
Life cycle of a bean:
https://howtodoinjava.com/spring-core/spring-bean-life-cycle/
implement BeanFactoryPostProcessors, BeanPostProcessor for checking when exactly the beans were created.

huangapple
  • 本文由 发表于 2023年5月24日 19:31:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76323071.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定