Issue
As per my understanding, @Lazy annotation and lazy-init attribute of tag should have the same functionality. But when I developed the following code, it's showing distinct behaviours. In the following code, I was expecting :- (Circular Dependency Error)
org.springframework.beans.factory.BeanCurrentlyInCreationException
I have attached code using @Lazy annotation, as per my expectations it should not allow Circular Dependency.
@Component
public class A {
private B b;
@Autowired
public A(@Lazy B b) {
System.out.println("A.A() - 1-param Constructor");
this.b = b;
}
}
@Component
public class B {
private A a;
@Autowired
public B(A a) {
System.out.println("B.B() - 1-param Constructor");
this.a = a;
}
}
Main Class :
public class AnnotationApp{
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/ry/cfgs/annotationAppContext.xml");
B objB = ctx.getBean("b", B.class);
A objA = ctx.getBean("a", A.class);
}
}
Spring Configuration File :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.ry.beans.annotation"></context:component-scan>
</beans>
OUTPUT :-
A.A() - 1-param Constructor
B.B() - 1-param Constructor
Require explanation, why it's behaving like this?
Solution
From Spring Framework Documentation:
... you can also place the
@Lazy
annotation on injection points marked with@Autowired
or@Inject
. In this context, it leads to the injection of a lazy-resolution proxy.
So, in the following code:
@Autowired
public A(@Lazy B b) {
// ...
}
b
will be injected (autowired) on first access instead of on startup.
Now, if you change your code to the following:
@Autowired
public A(@Lazy B b) {
System.out.println("A.A() - 1-param Constructor");
System.out.println(b.toString());
this.b = b;
}
you will see that org.springframework.beans.factory.BeanCurrentlyInCreationException
is thrown.
Answered By - Minar Mahmud
Answer Checked By - Terry (JavaFixing Volunteer)