Zohar Cohen opened SPR-17602 and commented
Hi,
I am facing a strange behavior with dependency injection in my project, there is an unexpected initialization of one of our constructors.
I am using Spring 5.0.6.RELEASE with XML configuration, we have the following structure:
Entity P - this class depended on two entities and a String:
public class P {public class P {
public P(D1 d1, D2 d2, String input){
System.out.println("P Constructor: D1: "+d1+", D2: "+d2+" , Input: "+input);
}
}
Entity S - this class inject to the depended class, the class contains two constructors, we are initializing only the empty constructor
public class S {public class S {
public S() {
System.out.println("S Empty Constructor!");
}
public S(String str) {
System.out.println("S Argument Constructor!");
}
}
Entity D1
public class D1 {public class D1 {
public D1(String input) {
System.out.println("D1 Constructor with input: " + input);
}
public D1(S s, String input) {
System.out.println("D1 Constructor with two inputs");
}
}
Entity D2
public class D2 {public class D2 {
public D2(String input) {
System.out.println("D2 Constructor with input: " + input);
}
public D2(S s, String input) {
System.out.println("D2 Constructor with two inputs");
}
}
XML configuration:
<beans xmlns:context="http://www.springframework.org/schema/context"<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<bean id="p" class="com.zohar.P">
<constructor-arg ref="d1" />
<constructor-arg ref="d2" />
<constructor-arg value="MS" />
</bean>
<bean id="d1" class="com.zohar.D1">
<constructor-arg value="MS" />
</bean>
<bean id="d2" class="com.zohar.D2">
<constructor-arg value="MS" />
</bean>
<bean id="s" class="com.zohar.S" />
</beans>
Based on the configuration file, the following activities should happen:
1) S - calling to empty constructor.
2) P - we are calling to the contractors with two depended and MS string.
3) D2 - constructorr with one input 'MS'.
4) D1 - constructore with input 'MS'
The issue is that during the autowiring process Spring initializes the S constructor with the String argument which is not expected to be called.
Program Output:
S Argument Constructor!
D1 Constructor with input: MS
S Argument Constructor!
D2 Constructor with input: MS
P Constructor: D1: com.zohar.D1@4566e5bd, D2: com.zohar.D2@1ed4004b , Input: MS
S Empty Constructor!
This seems like a private case due to the second constructors that the depended class have (Seems like an issue with the reflection process).
The solution to this issue is to add the wrapper class as a type to the 'constructor-arg' tag:
\
Zohar
Affects: 5.0.6
Attachments: - SpringDI.zip (6.78 MB)
Comment From: spring-projects-issues
Zhang Jie commented
When you specify bean by
<bean id="d1" class="com.zohar.D1">
<constructor-arg value="MS" />
</bean>
Spring doesn't find constructor D1(String input)
at first time, it loops all of constructors declared by D1
, on my machine, the order is first D1(S s, String input)
, then D1(String input)
. When checking D1(S s, String input)
, S(String str)
is involved because of constructor-arg MS
, then Spring finally finds that D1(String input)
satisfies constructor-arg MS
instead of D1(S s, String input)
, the detail is in ConstructorResolver.java.
Your solution specifies type
in constructor-arg
, the code goes differently at here, when doesn't specify type
in constructor-arg
, valueHolder
will not be null
, while valueHolder
will be null when specify type
in constructor-arg
.
Comment From: bclozel
Closing per https://github.com/spring-projects/spring-framework/issues/22134#issuecomment-453480451, this question has been answered.