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

165 views Asked by At

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?

2

There are 2 answers

0
user21909039 On BEST ANSWER

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

0
Vashista Basava On

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.