创建对象给属性赋值
DI的分类
1. set注入:spring调用类的set方法,在set方法可以实现属性的赋值
2. 构造注入:spring调用类的有参构造方法,创建对象,在构造方法中完成赋值
基于XML的依赖注入
1、set注入(设置注入)
spring调用set方法,完成属性赋值
1)简单类型的set注入
语法
<bean id="xx" class="yy">
<propery name="属性名1" value="属性性值"/>
<propery name="属性名2" value="属性值" />
...
</bean>
实体类
public class student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName"+name);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("setAge"+age);
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
beans
<bean id="student" class="cn.com.Ycy.spring.Beans.student">
<property name="name" value="张三"/>
<property name="age" value="21"/>
</bean>
测试类:
@Test
public void test5(){
String config = "bean01/applicationContext.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
Object student = ac.getBean("student");
System.out.println(student);
}
总结
1.就是<property name="name" value="张三"/>这个就是调用setName("张三");方法
2.并且实体类中必须有set方法,不然会报错:
Bean property 'age' is not writable or has an invalid setter method.
3. 如果没有属性比如id,但是xml文件写了,并且实体类中有setId()这个方法,是可以运行的
<property name="id" value="001"/>
原因:<property name="xx" value="001"/>就是调用实体类中的setXx()方法
4.所以由3可知,可以给非自定义类设置值,只要它的里面有setXx()方法就可以
2)引用类型的set注入
语法
<bean id="xx" class="yy">
<propery name="属性名1" value="属性性值"/>
<propery name="属性名2" value="属性值" />
<!--引用类型-->
<propery name="属性名3" ref="bean的id值"/>
...
</bean>
代码演示
实体类
public class student {
private String name;
private int age;
private school schools;
public school getSchools() {
return schools;
}
public void setSchools(school schools) {
this.schools = schools;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName"+name);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("setAge"+age);
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
", schools=" + schools +
'}';
}
}
beans中:
<bean id="student" class="cn.com.Ycy.spring.Beans.student">
<property name="name" value="张三"/>
<property name="age" value="21"/>
<property name="schools" ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
测试类
@Test
public void test5(){
String config = "bean01/applicationContext.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
Object student = ac.getBean("student");
System.out.println(student);
}
2、构造注入
spring调用类有参构造方法,在创建对象的同时,在构造方法中给属性赋值
构造注入使用 :< constructor-arg >标签
语法详解
< constructor-arg >标签:
一个表示构造方法的一个参数
< constructor-arg>标签属性:
name: 表示构造方法的形参名
index:表示构造方法的参数位置,参数从左往右的顺序是 0、1、2…
value:构造方法的形参类型是简单类型,使用value
ref:构造方法的形参类型是引用类型,使用ref,就是引入在ioc容器中存在的对象
使用name属性构造方法注入
代码
实体类
public class student {
private String name;
private int age;
private school schools;
public student() {
System.out.println("无参构造方法");
}
public student(String name, int age, school schools) {
this.name = name;
this.age = age;
this.schools = schools;
}
public school getSchools() {
return schools;
}
public void setSchools(school schools) {
this.schools = schools;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName"+name);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("setAge"+age);
this.age = age;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
", schools=" + schools +
'}';
}
}
//school类
public class school {
private String name;
private String address;
private int id;
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "school{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
", id=" + id +
'}';
}
}
bean.xml
<bean id="student" class="cn.com.Ycy.spring.Beans.student">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="20"/>
<constructor-arg name="schools" ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
测试类
@Test
public void test06(){
String config = "bean01/applicationContext.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
Object student = ac.getBean("student");
System.out.println(student);
}
使用index属性构造方法注入,就是beans.xml不同
<bean name="mystudent" class="cn.com.Ycy.spring.Beans.student">
<constructor-arg index="0" value="李四"/>
<constructor-arg index="1" value="21"/>
<constructor-arg index="2" ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
省略index也是可以的
<bean name="mystudent" class="cn.com.Ycy.spring.Beans.student">
<constructor-arg value="李四"/>
<constructor-arg value="21"/>
<constructor-arg ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
在这也是可以使用构造注入,创建非自定义的类,如File,Date…
引用类型的自动注入
Spring框架根据数据某些规则给引用类型赋值,不用我们在给引用类型赋值
分类:
1. byName
2. byType
1、byName:(按照名称注入): Java类中引用类型的属性名和Spring容器中的配置文件的id名称一样,且数据类型是一致的,这样容器中的bean,Spring会自动给引用类型赋值。
语法:
<bean id="xx" class="yy" autowire="byName">
简单数据类型属性赋值
</bean>
beans.xml文件
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
<bean id="student2" class="cn.com.Ycy.spring.Beans.student" autowire="byName">
<property name="name" value="王二"/>
<property name="age" value="21"/>
</bean>
测试类
@Test
public void test08(){
String config = "bean01/applicationContext.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
Object student = ac.getBean("student2");
System.out.println(student);
}
个人理解:
autowire=“byName”:创建对象时,spring就找cn.com.Ycy.spring.Beans.student的类的引用类型属性名
在用这个引用类型名去找和这个值相同的id
2、byType:按类型注入
Java类中的引用类型的数据类型和Spring容器中(配置文件)的class是同源的关系,这样才可以赋值给引用类型。
同源关系:
- java类中的引用类型的数据类型和bean的class的值是一样的
- java类中的引用类型的数据类型和bean的class的值是父子关系的
- java类中的引用类型的数据类型和bean的class的值是接口和实现类关系
就好像是这样的关系
private school schools = new xxx();
1. school school = new school();
2. school school = new primarySchool();(父子关系)
2. school school = new schoolImp();接口和实现类关系分析:
<bean id="student2" class="cn.com.Ycy.spring.Beans.student" autowire="byType">
<property name="name" value="王二"/>
<property name="age" value="21"/>
</bean>
<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
public class student {
private String name;
private int age;
private school schools;
}
就是把
<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>
这个赋值给private school school
private school school =
<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
<property name="name" value="北京大学"/>
<property name="address" value="北京"/>
<property name="id" value="0052"/>
</bean>