1

Consider the following code:
Here is class A

public class A {

    public A() {
        System.out.println("Creating instance of A");
    }

    private B b;

    public void setB(B b) {
        System.out.println("Setting property b of A instance");
        this.b = b;
    }

}

Here is class B

public class B {

    public B() {
        System.out.println("Creating instance of B");
    }

    private A a;

    public void setA(A a) {
        System.out.println("Setting property a of B instance");
        this.a = a;
    }

}

We have this configuration file:

<bean id="a" class="mypackage.A">
    <property name="b" ref="b" />
</bean>

<bean id="b" class="mypackage.B">
    <property name="a" ref="a" />
</bean>

Output:

Creating instance of A
Creating instance of B
Setting property a of B instance
Setting property b of A instance

when a is injected into b, a is not yet fully initialized.

My question:
Even though 'a' is not fully initialized when 'b' gets reference to 'a' , but after few moments 'a' will be completely initialized. Since 'b' has a reference to 'a', then 'b' will be pointing to fully initialized 'a' after few moments. This explanation is generally given to show disadvantage of circular dependency. But in the end we have a normal situation of both fully initialized beans 'a' and 'b' pointing to each other. Hence, how does this example show us disadvantage of using circular dependency ?

I would quote from spring docs:

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken/egg scenario)

Reference : Example taken from Circular dependency in spring

Community
  • 1
  • 1
Number945
  • 4,631
  • 8
  • 45
  • 83
  • What is the question? Spring does support circular dependency – Hurda Oct 06 '16 at 20:24
  • yes it does but it is not advised to use it. The reason they give is shown above. My counter argument is also shown above too. – Number945 Oct 06 '16 at 20:43
  • 1
    Now try and add an `@PostConstruct` method an both in which `A` uses `B` and `B` uses `A`. One of them will break. As either A isn't fully initialized before use or B isn't fully initialized when being used. If for whatever reasion you have a non-side effect free setter, it could also break. Having circular dependencies makes your code brittle and can lead to weird behavior at runtime (especially in startup/init code). Not to mention depending on the need it might even confuse the compiler. – M. Deinum Oct 07 '16 at 07:41

1 Answers1

-1

The Spring docs explains the dependency resolution process.

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken/egg scenario).

The beans are instantiated first, then injected into each other.

This is why Spring requires a constructor with no arguments ;-)

Sundararaj Govindasamy
  • 8,180
  • 5
  • 44
  • 77
  • Why circular dependency not advised ? For that, above example is generally given. But how is above example showing us disadvantage of circular dependency even though bean 'a' gets fully initialized after some time ? – Number945 Oct 06 '16 at 20:49
  • What is your problem? – Sundararaj Govindasamy Oct 06 '16 at 20:50
  • Bean 'a' gets fully initialized. Bean 'b' points to it. circular dependency is no hindrance in above example. So, why is above example told to show disadvantage of circular dependency. – Number945 Oct 06 '16 at 20:52