Issue
In a constructor with 2 arguments, I want to explicitly wire one and autowire the other.
Something like:
public Obj(Interface arg, Interface arg2) {
// stuff
}
And in the bean definition:
<bean id="objImpl" class="com.work.Obj">
<constructor-arg index="0" ref="interfaceImpl"/>
<constructor-arg index="1" autowire-this-somehow/>
</bean>
Does anyone know of a way ?
Solution
Try this:
<bean id="objImpl" class="com.work.Obj" autowire="constructor">
<constructor-arg index="0" ref="interfaceImpl"/>
</bean>
Here, you have specified that bean of type com.work.Obj
should created using constructor autowiring. If you specify any constructor arg, then it overrides autowired arg. So index 0 is explicitly provided. Other args which are not explicitly provided will be autowired by type.
Caution: constructor autowiring has the same limitation as byType
- Spring won't attempt to guess which bean to autowire when it finds multiple beans that match a constructor arg. Further, if the class has multiple constructors, any of which can be satisfied by autowiring, then Spring won't attempt to guess which constructor to use. You will get an exception in this case.
EDIT: For this to work, other beans of type Interface
(constructor arg type) except the one that needs to be autowired, should be marked with autowire-candidate=false
Example:
<bean id="impl1" class="stackoverflow.SomeImpl" autowire-candidate="false"/>
<bean id="impl2" class="stackoverflow.SomeImpl"/>
<bean id="obj" class="stackoverflow.Obj" autowire="constructor">
<constructor-arg index="0" ref="impl1"/>
</bean>
And Obj class:
package stackoverflow;
public class Obj {
public Obj(SomeInterface i1, SomeInterface i2){
System.out.println("i1" + i1);
System.out.println("i2" + i2);
}
}
Here SomeImpl implements SomeInterface
. On running impl2
bean is autowired in the second constructor arg i2
. The first arg is manually provided in Spring config.
Answered By - Pat
Answer Checked By - Mildred Charles (JavaFixing Admin)