Reputation: 863
I have two classes Test and SampleClassWithMultipleProperty for which I have bean definitions as follows:
<bean name="test" class="Test" autowire="constructor">
</bean>
<bean id="instance1" class="SampleClassWithMultipleProperty">
<constructor-arg type="java.lang.String" value="constructor-arg-1"/>
<constructor-arg type="java.lang.String" value="constructor-arg-2"/>
<constructor-arg type="java.lang.String" value="constructor-arg-3"/>
<constructor-arg type="int" value="4"/>
<constructor-arg type="java.lang.Integer" value="5"/>
</bean>
When I specify any name id like for example "instance1" ,"instance2","instance3" it works.
But when I have another bean of same type SampleClassWithMultipleProperty as follows :
<bean id="instance2" class="SampleClassWithMultipleProperty">
<constructor-arg type="java.lang.String" value="constructor-arg-1-ind"/>
<constructor-arg type="java.lang.String" value="constructor-arg-2-ind"/>
<constructor-arg type="java.lang.String" value="constructor-arg-3-ind"/>
<constructor-arg type="int" value="4"/>
<constructor-arg type="java.lang.Integer" value="5"/>
</bean>
The container is not able to initialize the bean instance of SampleClassWithMultipleProperty (with name sampleClassWithMultipleProperty) inside the Test class (Has a relation).
It successfully does that when I change any of the ids of the bean from "instance1" to "sampleClassWithMultipleProperty" OR "instance2" to "sampleClassWithMultipleProperty" .
But why is it behaving like this. I read somewhere that autowiring by constructor is similar to autowiring byType. So ideally it should match the type of the bean i.e. class name.
Please find my classes below:
public class Test {
SampleClassWithMultipleProperty sampleClassWithMultipleProperty;
public Test() {
super();
// TODO Auto-generated constructor stub
}
public Test(SampleClassWithMultipleProperty sampleClassWithMultipleProperty) {
super();
System.out.println("in Test constructor");
this.sampleClassWithMultipleProperty = sampleClassWithMultipleProperty;
}
public SampleClassWithMultipleProperty getSampleClassWithMultipleProperty() {
return sampleClassWithMultipleProperty;
}
public void setSampleClassWithMultipleProperty(
SampleClassWithMultipleProperty sampleClassWithMultipleProperty) {
this.sampleClassWithMultipleProperty = sampleClassWithMultipleProperty;
}
}
public class SampleClassWithMultipleProperty {
private String property1;
private String property2;
private String property3;
private int property4;
private Integer property5;
public SampleClassWithMultipleProperty() {
super();
// TODO Auto-generated constructor stub
}
public SampleClassWithMultipleProperty(String property1, String property2, String property3,
int property4, Integer property5) {
super();
this.property1 = property1;
this.property2 = property2;
this.property3 = property3;
this.property4 = property4;
this.property5 = property5;
}
public String getProperty1() {
return property1;
}
public void setProperty1(String property1) {
this.property1 = property1;
}
public String getProperty2() {
return property2;
}
public void setProperty2(String property2) {
this.property2 = property2;
}
public String getProperty3() {
return property3;
}
public void setProperty3(String property3) {
this.property3 = property3;
}
public int getProperty4() {
return property4;
}
public void setProperty4(int property4) {
this.property4 = property4;
}
public Integer getProperty5() {
return property5;
}
public void setProperty5(Integer property5) {
this.property5 = property5;
}
}
Upvotes: 2
Views: 743
Reputation: 3041
Your Test
bean has 2 constructors : a no arg constructor and a constructor that needs an instance of a SampleClassWithMultipleProperty
.
When you only have one SampleClassWithMultipleProperty
instance in your classpath spring will just choose the constructor that takes a SampleClassWithMultipleProperty
.
When you have two SampleClassWithMultipleProperty
spring won't be able to choose between them so the no arg constructor is going to be chosen.
When you are changing the id
of one of your SampleClassWithMultipleProperty
bean that match the name of the parameter of the constructor spring will be able to choose between them and will be able to create your bean with the constructor that expect an instance of SampleClassWithMultipleProperty
.
If in the second case (2 SampleClassWithMultipleProperty
beans and none matching the parameter's name) you would have had a NoUniqueBeanDefinitionException
because spring would not have been able to use a proper constructor to build your bean.
Spring will automatically choose the constructor satisfying the most parameters possible.
Upvotes: 1
Reputation: 3227
Hi I am not a spring expert but I know some bits and did some searching around and I would like to answer on basis of that.
I assume you have default-autowire by id. You have two bean definitions of class SampleClassWithMultipleProperty. This both are eligible for creation and to be used as constructor arg for Test.
By default, autowiring scan and matches all bean definitions in scope. If you want to exclude some bean definitions so that they can not be injected through autowiring mode, you can do this using autowire-candidate
set to false.
So what you can do is:
<bean id="instance2" class="SampleClassWithMultipleProperty" autowire-candidate="false">
Also you have option to use default-autowire-candidates
property which should help you out here. You can just pass a pattern which will be used to scan the probable candidates for bean creation.
Reference Link 1
Reference Link 2
Reference Link 3
Upvotes: 1