依赖注入是ioc的具体实现方式,ioc从当前资源获取角度,原来需要自动获取,现在需要被动接受,ioc具体的实现DI依赖注入。为当前类中的属性进行赋值的过程就叫做依赖注入。
set注入
就是提前通过当前为属性为成员变量提前设置好的一些方式。
applictioncontext配置文件中,bean标签的property就是set注入。
组件(实体类)
public class Student {
private Integer sid;
private String sname;
private Integer age;
private String gender;
public Student() {
}
....
}
applicationcontext.xml配置文件
<!--set注入-->
<!--
property:通过成员变量的set方法进行赋值
name:设置需要赋值的属性名
value:设置为属性所赋的值
-->
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1001"></property>
<property name="sname" value="张三"></property>
<property name="age" value="23"></property>
<property name="gender" value="男"></property>
</bean>
构造器注入
如果实体类组件中有多个有参构造,指定通过哪个有参构造注入,就需要通过不相同的有参构造的参数加上name属性标记。
applicationcontext.xml配置文件
name参数名,如果类中只有一个有参构造的话,可以不用写name属性,直接为参数按顺序赋值
-->
<bean id="student" class="com.atguigu.spring.pojo.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
<constructor-arg value="男"></constructor-arg>
</bean>
特殊值处理注入
1. 字面量赋值
什么是字面量?
int a = 10;
声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a
的时候,我们实际上拿到的值是10。
而如果a是带引号的:'a',那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面
量。所以字面量没有引申含义,就是我们看到的这个数据本身。
<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>
2.为属性赋null值
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1003"></property>
<property name="sname" value="王五"></property>
<property name="age" value="25"></property>
<!-- 为属性赋值为null-->
<property name="gender">
<null />
</property>
</bean>
3. XML实体
第一种方法:
两个相对应
<:<;
>:>;
第二种方法:CDATA
CDATA节是xml中一个特殊的标签,因此不能写在一个属性中,只能以标签的方式使用。
<property name="expression">
<!-- 解决方案二:使用CDATA节 -->
<!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
<!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
<!-- 所以CDATA节中写什么符号都随意 -->
<value><![CDATA[a < b]]></value>
</property>
为类类型属性赋值(引用外部bean)
1. 引用外部bean
ref属性:引用IOC容器中的某个bean的id
也就是为类的类型的对象进行引用
实体类/组件
package com.atguigu.spring.pojo;
public class Student {
private Integer sid;
private String sname;
private Integer age;
private String gender;
//对应对应对象,对多对应集合,学生对应班级:对一
private Clazz clazz;
public Student() {
}
.......
}
package com.atguigu.spring.pojo;
public class Clazz {
private Integer cid;
private String cname;
public Clazz() {
}
....
}
ApplicationContext.xml文件
<!-- ref:引用,引用当前ioc容器中的某个bean的id为当前属性赋值 -->
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
<property name="clazz" ref="clazzOne"></property>
</bean>
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="12"></property>
<property name="cname" value="最强软件班"></property>
</bean>
2. 级联方式 (不常用)
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
<property name="clazz" ref="clazzOne"></property>
<!--级联方式,要保证提前为clazz属性赋值(覆盖了)或者实例化-->
<property name="clazz.cid" value="22"></property>
<property name="clazz.cname" value="前程班"></property>
</bean>
<bean id="clazzOne" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="12"></property>
<property name="cname" value="最强软件班"></property>
</bean>
3. 内部bean
在property标签里面通过bean标签设置一个对象,为当前属性赋值。
ApplicationContext.xml文件
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
<property name="clazz">
<bean id="clazzInner" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="1"></property>
<property name="cname" value="前程班"></property>
</bean>
</property>
</bean>
测试方法
如果用的是内部bean,当前内部bean只能在bean的内部使用,
是无法通过ioc直接获取的。
@Test
public void TestIOC(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("Applicationcontext.xml");
Student student = applicationContext.getBean(Student.class);
Clazz clazz = applicationContext.getBean(Clazz.class);
System.out.println(student); //可以获取
System.out.println(clazz); //报错 当前内部bean只能在bean的内部使用,是无法通过ioc直接获取的。
}
为数组类型属性赋值
1. 内部list集合
实体类/组件
public class Clazz {
private Integer cid;
private String cname;
//一对多,用list集合,list集合里面存储的是类类型
private List<Student> students;
...
}
public class Student {
private Integer sid;
private String sname;
private Integer age;
private String gender;
public Student() {
}
.......
}
ApplicationContext.xml文件
<bean id="studentOne" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
</bean>
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1005"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
</bean>
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1006"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
</bean>
<bean id="clazz" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="111"></property>
<property name="cname" value="最强王者班"></property>
<property name="students">
<list>
<!-- list里面存储的是类类型,所以ref -->
<ref bean="studentOne"></ref>
<ref bean="studentTwo"></ref>
<ref bean="studentThree"></ref>
</list>
</property>
</bean>
2. 引用list集合类型的bean
ApplicationContext.xml文件
<bean id="studentOne" class="com.atguigu.spring.pojo.Student">
......
</bean>
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student">
.....
</bean>
<bean id="studentThree" class="com.atguigu.spring.pojo.Student">
.....
</bean>
<bean id="clazz" class="com.atguigu.spring.pojo.Clazz">
<property name="cid" value="111"></property>
<property name="cname" value="最强王者班"></property>
<property name="students" ref="studentlist"></property>
</bean>
<!-- 配置一个集合类型的bean,需要使用util的约束 -->
<util:list id="studentlist">
<ref bean="studentOne"></ref>
<ref bean="studentTwo"></ref>
<ref bean="studentThree"></ref>
</util:list>
为Map集合类型属性赋值
方法1:
在property里面设置设置map值。
实体类/组件
package com.atguigu.spring.pojo;
public class Teacher {
private Integer tid;
private String tname;
public Teacher() {
}
....
}
public class Student {
private Integer sid;
private String sname;
private Integer age;
private String gender;
private Map<String,Teacher> teacherMap;
public Student() {
}
....
}
ApplicatonContext.xml文件
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
<property name="teacherMap">
<map>
<!-- entry:表示键值对 把id作为键,对象作为值 -->
<entry key="1000001" value-ref="teacherOne"></entry>
<entry key="1000002" value-ref="teacherTwo"></entry>
</map>
</property>
</bean>
<bean id="teacherOne" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="1000001"></property>
<property name="tname" value="大宝"></property>
</bean>
<bean id="teacherTwo" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="1000002"></property>
<property name="tname" value="小宝"></property>
</bean>
测试方法
@Test
public void TestIOC(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("Applicationcontext.xml");
Student student= applicationContext.getBean(Student.class);
System.out.println(student);
}
方法2:
ApplicationContext.xml文件
<bean id="student" class="com.atguigu.spring.pojo.Student">
<property name="sid" value="1004"></property>
<property name="sname" value="赵六"></property>
<property name="age" value="25"></property>
<property name="gender" value="男"></property>
<!--直接引用teachMap-->
<property name="teacherMap" ref="teacherMap"></property>
</bean>
<util:map id="teacherMap">
<entry key="100001" value-ref="teacherOne"></entry>
<entry key="100002" value-ref="teacherTwo"></entry>
</util:map>
<bean id="teacherOne" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="1000001"></property>
<property name="tname" value="大宝"></property>
</bean>
<bean id="teacherTwo" class="com.atguigu.spring.pojo.Teacher">
<property name="tid" value="1000002"></property>
<property name="tname" value="小宝"></property>
</bean>
xml和注解方式两种在什么情况下使用
两个一起使用,基于注解加在类上的,基于xml是要写在xml中,
如果是自己写创建的类,可以加上注解,如果用的是第三方类库,
要把第三方类库交 给ioc管理,只能xml方式。