英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论