基于构造函数的 DI 是通过容器调用具有多个参数的构造函数来完成的。
准备工作
创建一个有三个变量的类 User
,加入set()
,get()
方法,以及自定义一个输出值的方法 show()
User类
代码如下:
public class User {
private String name;
private int age;
private String sex;
public User(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void show() {
System.out.println("name = "+name+",age = "+age+",sex = "+sex);
}
}
注意点:
三种构造器注入方式分别是为了适应不同的构造器重载方式而存在的,尤其是第二种按类型注入:假如某类有多个构造器,变量都只有一个只是传入类型不同,那么此时为了区分重载就只能使用第二种按类型注入的方式。
一、通过索引取值
<bean id="user" class="com.yafnds.pojo.User">
<constructor-arg index="0" value="name1"/>
<constructor-arg index="1" value="1"/>
<constructor-arg index="2" value="man"/>
</bean>
二、通过参数类型取值
<bean id="user2" class="com.yafnds.pojo.User">
<constructor-arg type="java.lang.String" value="name2"/>
<constructor-arg type="int" value="2"/>
<constructor-arg type="java.lang.String" value="man2"/>
</bean>
注意点:
- 当注入类型为引用类型时,需填入完全限定名;而基础类型则不用
- 当参数类型相同时,该方法会根据顺序来确定对应的参数,如果调换位置,值也会错位
例:将 sex 的顺序与 name 互换
结果:
三、通过参数名取值
<bean id="user3" class="com.yafnds.pojo.User">
<constructor-arg name="name" value="name3"/>
<constructor-arg name="age" value="3"/>
<constructor-arg name="sex" value="man3"/>
</bean>
四、直接传值
<bean id="user4" class="com.yafnds.pojo.User">
<constructor-arg value="name4"/>
<constructor-arg value="4"/>
<constructor-arg value="man4"/>
</bean>
注意点:
- 该方法根据顺序排序,一旦调换位置,Spring就会开始判断传入的值是否符合该类型,如果不符合,则报错
例:将 age 和 name 互换
结果:
报错内容:
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘user4’ defined in class path resource [beans.xml]: Unsatisfied dependency expressed through constructor parameter 1: Could not convert argument value of type [java.lang.String] to required type [int]: Failed to convert value of type ‘java.lang.String’ to required type ‘int’; nested exception is java.lang.NumberFormatException: For input string: “name4”