bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:
- setter注入
- 构造器注入
目录
setter注入
setter注入也叫设值注入,是指通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
(1)基本数据类型注入
定义实现类
public class Students {
private String name;
private int age;
private School school;
public Students() {
System.out.println("无参构造启动...");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSchool(School school) {
this.school = school;
}
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
在applicationContext.xml文件中配置bean实例已经依赖注入
<bean id="stu" class="com.muyu.pojo.Students">
<property name="name" value="张三"/>
<property name="age" value="11"/>
</bean>
测试代码
// 测试类
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Students stu = (Students) ac.getBean("stu");
System.out.println(stu);
// 无参构造启动...
// Students{name='张三', age=11}
(2)引用类型
当指定 bean 的某属性值为另一 bean的实例时,通过ref指定它们间的引用关系。ref的值必须为某一bean的 id 值。该属性值依赖于另一bean实例进行注入,称为依赖注入。
public class School {
private String name;
private String address;
public School() {
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
<bean id="school" class="com.muyu.pojo.School"></bean>
<bean id="stu" class="com.muyu.pojo.Students">
<property name="name" value="张三"/>
<property name="age" value="11"/>
<property name="school" ref="school"/> // 依赖于id为school的bean实例进行注入
</bean>
// School实现类增加List<>引用类型
public class School {
private String name;
private String address;
private List<Integer> classes;
...
集合类型注入
当集合类型进行注入时,使用相应标签(list、set、array、map...)对属性值进行注入。
<bean id="school" class="com.muyu.pojo.School">
<property name="classes">
<list>
<value>10</value>
<value>11</value>
<value>12</value>
</list>
<!--
1. array集合
<array>
<value></value>
</array>
2. set集合
<set>
<value></value>
</set>
3. map集合
<map>
<entry value="" ket=""></entry>
</map>
-->
</property>
</bean>
小结:
- 使用setter注入时,必须要在对应实现类中指定setter方法,否则容器无法进行注入。
- 使用property标签来完成依赖注入。
- 使用"name" 属性用来指定类中的属性名,"value" 属性用来指定属性值。
- 对于基本数据类型(包括String),指定属性值使用"value"属性,而对于引用类型使用"ref"属性。
构造器注入
构造器注入,顾名思义使用实现类中的构造器,在applicationContext.xml文件中定义bean对象,并使用constructor-arg标签进行依赖注入,name属性要与实现类中提供的形参类型和个数一致,否则将会报错。
public Students(String name, int age, School school) {
this.name = name;
this.age = age;
this.school = school;
}
<bean id = "stu" class="com.muyu.pojo.Students">
<constructor-arg name="name" value="李四"/>
<constructor-arg name="age" value="21"/>
<constructor-arg name="school" ref="school"/>
</bean>
测试代码
@Test
public void Test03(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Students stu = (Students) ac.getBean("stu");
System.out.println(stu);
}
// Students{name='李四', age=21}
可以看出setter注入和构造器注入并无太大区别,一个是运用setter方法,一个是运用构造器,构造器注入将properties标签改完constructor-arg 即可。
构造器注入存在的缺点有constructor-arg标签中的name属性要与实现类构造器中的形参名一致,这就导致xml文件与实现类有较高的耦合度,因此较少使用构造器注入。
本文供学习参考,如存在问题,烦请大佬指出。