Reputation: 43
I am providing small code snippet first, then I shall ask for the explanation.
public class A {
private String msg;
private B b;
public A () {
System.out.println("No argument constructor is called");
}
public A (B b) {
System.out.println("Parameterized constructor is called");
this.b = b;
}
// getters and setters
}
==============================================
<bean id="a" class="A" p:msg="hello" autowire="constructor"/>
<bean id="b" class="B"/>
==============================================
OUTPUT:
Parameterized constructor is called
This is the normal behavior & understandable
Now, I am adding a new bean definition of class B, as given below.
<bean id="a" class="A" p:msg="hello" autowire="constructor"/>
<bean id="b" class="B"/>
<bean id="c" class="B"/>
So, as far I know, since autowiring through constructor internally uses 'byType', hence it will give an exception regarding bean uniqueness violation, e.g., this scenario occurs if I would have used autowire="byType".
But strangely, the output is given below.
OUTPUT:
No argument constructor is called
However, please note that if there is no default constructor specified in class A, then the expected exception will occur. So, is it a default behavior of Spring IoC container? If yes, then kindly explain me this in detail.
Thank you in advance.
The question is also available in LinkedIn (Spring autowiring through constructor ambiguity)
Upvotes: 4
Views: 2590
Reputation: 1
I tried above example:
A.java
package com.constructor;
public class A {
private String msg;
private B b;
public A () {
System.out.println("No argument constructor is called");
}
public A (B b) {
System.out.println("Parameterized constructor is called");
this.b = b;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
// getters and setters
}
Upvotes: 0
Reputation: 120811
If a class has multiple constructors, any of which can be satisfied by autowiring, then Spring will throw an exception as it cannot decide which bean to auto-wire.
http://www.studytrails.com/frameworks/spring/spring-auto-wire-constructor.jsp
So it mean if you have multiple constructors spring need to choose one. And spring is so intelligent to choose the one that it can wire. So it you have only on B bean it uses the constructor with B argument. If you have two B beans it can not use this constructor because of not unique B, so it fall back to default constructor. It you delete this constructor you get the exception.
Upvotes: 1