1.简单类型属性的赋值(set注入)
set注入要求
JavaBean必须要有set方法,因为ioc容器是使用javabean的set方法进行属性赋值的
spring容器调用的是setXxx()方法,而不管对象是否具有Xxx属性(即对象没有的属性只要有set方法也可以实现注入),Xxx不区分大小写
JavaBean
public class Student {
private String name;
private int age;
private School school;
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
spring配置文件
<!--声明Student对象-->
<bean id="student" class="com.mms.component.Student">
<!--
1、简单类型使用property和value标签给对象属性赋值
2、简单类型:8个基本类型+String
3、当spring容器加载到这一行时会在创建完对象的同时使用对象的set方法给属性赋值,底层
调用的是对象的set方法
4、spring容器调用的是setXxx()方法,而不管对象是否具有Xxx属性,Xxx不区分大小写
-->
<property name="name" value="张三"/>
<property name="age" value="23"/>
<!--测试对象没有属性的set方法-->
<property name="graName" value="s1"/>
</bean>
测试类
//使用set注入给对象属性赋值
@Test
public void test01() {
String config = "ba01/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//执行完14行此时Student对象的属性已被赋值,获取对象进行验证
Student stu = (Student) ac.getBean("student");
System.out.println(stu); //Student{name='张三', age=23}
}
//验证set注入调用的是对象的set方法
@Test
public void test02() {
String config = "ba01/applicationContext.xml";
/*
* 此时会调用set方法进行赋值
* setName...
* setAge...
*/
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
}
//验证没有属性的setXxx方法是否报错
@Test
public void test03() {
String config = "ba01/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//获取对象
Student stu = (Student) ac.getBean("student");
}
2.非简单类型属性的赋值(set注入)
上文中的set注入使用property标签的name和value属性给对象属性赋值,但是value知识给简单类型属性赋值,对于非简单类型我们是使用property标签的name和ref属性给对象属性赋值。我们现在给Student类增加一个属性address,该属性是一个引用类型,那当ioc容器创建Student对象时如何给address属性赋值呢?
JavaBean
//引用类型属性
private Address address;
public void setAddress(Address address) {
System.out.println("引用类型address的set方法执行了...");
this.address = address;
}
JavaBean
public class Address {
private String homeAddress;
private String schoolAddress;
public void setHomeAddress(String homeAddress) {
this.homeAddress = homeAddress;
}
public void setSchoolAddress(String schoolAddress) {
this.schoolAddress = schoolAddress;
}
@Override
public String toString() {
return "Address{" +
"homeAddress='" + homeAddress + '\'' +
", schoolAddress='" + schoolAddress + '\'' +
'}';
}
}
spring配置文件
<!--声明Student对象-->
<bean id="student" class="com.mms.component.Student">
<property name="name" value="张三"/>
<property name="age" value="23"/>
<!--测试对象没有属性的set方法-->
<property name="graName" value="s1"/>
<!--
引用类型属性的set注入
property标签属性
name:属性名
ref:引用对象的id值
-->
<property name="address" ref="address"/>
</bean>
<!--Student对象的引用属性Address-->
<bean id="address" class="com.mms.component.Address">
<!--set注入-->
<property name="homeAddress" value="新疆"/>
<property name="schoolAddress" value="西安"/>
</bean>
上文执行流程分析:当ioc容器创建id为student的对象时,会进行set注入,当执行到最后一个propert标签时发现使用了ref属性,则ioc容器知道了name为address的属性是非简单类型,它就会暂时跳过address属性的赋值以及Student对象的创建,转而去配置文件的下文去找bean标签id值等于ref属性值的对象,现将该对象创建,再将该对象赋值给之前的address属性并将Student对象创建。
3.构造注入
顾名思义,构造注入是使用javabean的构造方法进行属性的赋值的。与set注入一样,构造注入要求javabean必须提供构造方法,且必须是有参构造(如果是无参构造还怎么给属性赋值,对吧),构造注入使用较少,了解就可以了,我们一般使用set注入。看看代码吧,将Student类的set方法注释,加入构造方法,别的地方不用改变,只需要改变spring配置文件即可(这里就可以看出ioc容器与程序的解耦合的好处了)。
<bean id="user" class="com.chang.pojo.User"> <constructor-arg name="name" value="cyq1"/> </bean> <bean id="user" class="com.chang.pojo.User"> <constructor-arg index="0" value="cyq2"/> </bean> <bean id="user" class="com.chang.pojo.User"> <constructor-arg type="java.lang.String" value="Cyq3"/> </bean>