在Spring框架中,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题。
看如下一个代码:
public
class
Student {
private
String
name
;
private
String
address
;
private
int
age
;
public
Student(String
name
, String
address
,
int
age
) {
super
();
this
.
name
=
name
;
this
.
address
=
address
;
this
.
age
=
age
;
}
public
Student(String
name
,
int
age
, String
address
) {
super
();
this
.
name
=
name
;
this
.
address
=
address
;
this
.
age
=
age
;
}
public
String getName() {
return
name
;
}
public
void
setName(String
name
) {
this
.
name
=
name
;
}
public
String getAddress() {
return
address
;
}
public
void
setAddress(String
address
) {
this
.
address
=
address
;
}
public
int
getAge() {
return
age
;
}
public
void
setAge(
int
age
) {
this
.
age
=
age
;
}
@Override
public
String toString() {
return
"Student [name="
+
name
+
", address="
+
address
+
", age="
+
age
+
"]"
;
}
}
在Spring bean的配置文件中,name为jack,adderss为123456,age为12:
<
beans
xmlns
=
" http://www.springframework.org/schema/beans"
;
xmlns:xsi
=
" http://www.w3.org/2001/XMLSchema-instance"
;
xmlns:p
=
" http://www.springframework.org/schema/p"
;
xsi:schemaLocation
=
" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
;
>
<
bean
id
=
"StudentBean"
class
=
"com.yiibai.dao.Student"
>
<
constructor-arg
><
value
>
jack
value
>
constructor-arg
>
<
constructor-arg
><
value
>
123456
value
>
constructor-arg
>
<
constructor-arg
><
value
>
12
value
>
constructor-arg
>
bean
>
beans
>
执行如下代码:
public
static
void
main(String[]
args
) {
ApplicationContext
context
=
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
Student
student
= (Student)
context
.getBean(
"StudentBean"
);
System.
out
.println(
student
);
}
我们期望的输出结果为:
Student [name=jack, address=123456, age=12]
实际的输出结果为:
Student [name=jack, address=12, age=123456]
我们期望的是它调用第一个构造函数来注入属性的,但实际上调用的是第二个构造函数,
在Spring参数类型'123456' 能够转换成int,所以Spring只是转换它,并采用第二个构造来执行,即使你认为它应该是一个字符串。
这样就造成了属性注入问题。
为了解决这个问题,应该为构造函数指定确切的数据类型,Spring bean的配置文件应该修改为如下形式:
<
beans
xmlns
=
" http://www.springframework.org/schema/beans"
;
xmlns:xsi
=
" http://www.w3.org/2001/XMLSchema-instance"
;
xmlns:p
=
" http://www.springframework.org/schema/p"
;
xsi:schemaLocation
=
" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
;
>
<
bean
id
=
"StudentBean"
class
=
"com.yiibai.dao.Student"
>
<
constructor-arg
type
=
"java.lang.String"
><
value
>
jack
value
>
constructor-arg
>
<
constructor-arg
type
=
"java.lang.String"
><
value
>
123456
value
>
constructor-arg
>
<
constructor-arg
type
=
"int"
><
value
>
12
value
>
constructor-arg
>
bean
>
beans
>
输出结果为:
Student [name=jack, address=123456, age=12]
因此,为了解决这个问题可以为构造函数指定确切的数据类型,但是这样做其实还是很麻烦,所以,个人建议属性注入可以使用setter方法。