目录
一、什么是依赖注入
简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值。
二、DI_依赖注入三种方式
1.Setter注入
2.构造方法注入
3.自动注入
自动注入有两种配置方式:
autowire的取值如下:
测试自动注入:
三、DI_依赖注入类型
1.在被注入类中编写需要注入的属性名及类型
2.测试方法
3.在xml文件中编写注入代码
(1)注入bean类型:private StudentDao studentDao;
(2)注入基本数据类型:private String name; //字符串类型 private int count; //基本数据类型
(3)注入List集合:private List names; // 字符串类型List集合 private List students1; // 对象类型List集合
(4)注入Set集合:private Set students2; // 对象类型Set集合
(5)注入Map集合: private Map names2; //字符串类型Map集合 private Map students3;// 对象类型Map集合,student>,string>
(6)注入Properties对象:private Properties properties;//Properties类型
一、什么是依赖注入
依赖注入(Dependency Injection,简称DI),它是Spring控制反转思想的具体实现。
控制反转将对象的创建交给了 Spring ,但是对象中可能会依赖其他对象。比如service 类中要有 dao 类的属性,我们称 service 依赖于dao。之前需要手动注入属性值,代码如下:
public interface StudentDao {
Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
@Override
public Student findById(int id) {
// 模拟根据id查询学生
return new Student(1,"百战程序员","北京");
}
}public class StudentService {
// service依赖dao,手动注入属性值,即手动维护依赖关系
private StudentDao studentDao = new StudentDaoImpl();
public Student findStudentById(int id){
return studentDao.findById(id);
}
}
此时,当 StudentService 的想要使用 StudentDao 的另一个实现类如StudentDaoImpl2时,则需要修改 Java 源码,造成代码的可维护性降低。
而使用 Spring 框架后, Spring 管理 Service 对象与 Dao 对象,此时它能够为Service 对象注入依赖的 Dao 属性值。这就是 Spring 的依赖注入。
简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值。
二、DI_依赖注入三种方式
在之前的开发中,可以通过setter方法或构造方法设置对象的属性值,在Spring框架中,我们可以通过调用setter方法或构造方法给属性赋值。
1.Setter注入
(1)被注入类编写属性的setter方法:(setter注入需要在类中编写setter方法)
public class StudentService {
private StudentDao studentDao;
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
}
(2)配置文件中,给需要注入属性值的<bean>中设置<property>
<bean>:配置对象 <property>通过setter方法注入 <constructor-arg>通过构造器注入
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--依赖注入-->
<!--property:专门用于setter注入标签 name:StudentService类中的属性名 ref:容器中对象的id值-->
<property name="studentDao" ref="studentDao"></property>
</bean>
(3)测试是否注入成功
public class TestContainer {
@Test
public void t1(){
// 创建Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 从容器中获取对象
StudentService studentService = (StudentService) ac.getBean("studentService");
System.out.println(studentService);
System.out.println(studentService.getStudentDao());
System.out.println(studentService.findStudentById(1));
}
}
(4)测试结果
标明注入成功!
2.构造方法注入
(1)被注入类编写有参的构造方法:(构造方法注入需要在类中编写构造方法)
public class StudentService {
private StudentDao studentDao;
public StudentService(StudentDao studentDao) {
this.studentDao = studentDao;
}
}
(2)给需要注入属性值的<bean>中设置<constructor-arg>
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--依赖注入-->
<!--constructor-arg:专门用于构造方法注入标签 name:StudentService类中的属性名 ref:容器中对象的id值-->
<constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
</bean>
(3)测试是否注入成功、测试结果 如setter注入一样
3.自动注入
自动注入不需要在 <bean> 标签中添加其他标签注入属性值,而是自动从容器中找到相应的bean对象设置为属性值。
自动注入有两种配置方式:
1.全局配置:在 <beans> 中设置 default - autowire 属性可以定义 所有 bean 对象的自动注入策略。(一般不使用)
2.局部配置:在 <bean> 中设置 autowire 属性可以定义 当前 bean 对象的自动注入策略。(一般使用)
autowire的取值如下:
no :不会进行自动注入。
default :全局配置 default 相当于 no ,局部配置 default 表示使用全局配置
byName :在 Spring 容器中查找 id 与属性名相同的 bean ,并进行注入。需要提供 set 方法。
byType :在 Spring 容器中查找类型与属性类型相同的 bean ,并进行注入。需要提供 set 方
法。
constructor :在 Spring 容器中查找 id 与属性名相同的 bean ,并进行注入。需要提供构造方
法。
测试自动注入:
1.为依赖的对象提供setter和构造方法
public class StudentService {
// 依赖
private StudentDao studentDao;
// 构造方法
public StudentService() {
}
public StudentService(StudentDao studentDao) {
this.studentDao = studentDao;
}
// setter方法
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
// 调用依赖的方法
public Student findStudentById(int id) {
return studentDao.findById(id);
}
}
2.配置自动注入:
(1)配置局部自动注入
<!-- 根据beanId等于属性名自动注入 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService" autowire="byName"></bean><!-- 根据bean类型等于属性类型自动注入 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService"class="com.itbaizhan.service.StudentService" autowire="byType"></bean><!-- 利用构造方法自动注入 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService"class="com.itbaizhan.service.StudentService" autowire="constructor"></bean>
(2)配置全局自动注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="constructor">
三、DI_依赖注入类型
DI支持注入bean类型、基本数据类型和字符串、List集合、Set集合、Map集合、Properties对象类型等,他们的写法如下:
1.在被注入类中编写需要注入的属性名及类型
public class StudentService {
private StudentDao studentDao;//bean类型
private String name; //字符串类型
private int count; //基本数据类型
private List<String> names; // 字符串类型List集合
private List<Student> students1; // 对象类型List集合
private Set<Student> students2; // 对象类型Set集合
private Map<String,String> names2; //字符串类型Map集合
private Map<String,Student> students3;// 对象类型Map集合
private Properties properties;//Properties类型
// 省略getter/setter/toString
}
2.测试方法
@Test
public void t3(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
StudentService studentService = (StudentService)ac.getBean("studentService");
System.out.println(studentService);
}
3.在xml文件中编写注入代码
(1)注入bean类型:private StudentDao studentDao;
写法一:
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入bean写法一:-->
<property name="studentDao" ref="studentDao"></property>
</bean>
写法二:
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean>
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入bean写法二:-->
<property name="studentDao">
<ref bean="studentDao"></ref>
</property>
</bean>
(2)注入基本数据类型:private String name; //字符串类型
private int count; //基本数据类型
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入基本数据类型和字符串,写法一:name:属性名 value:属性值-->
<property name="name" value="写法"></property>
<!--注入基本数据类型和字符串,写法二:name:属性名 value:属性值-->
<property name="count">
<value>10</value>
</property>
</bean>
(3)注入List集合:private List<String> names; // 字符串类型List集合
private List<Student> students1; // 对象类型List集合注入简单数据类型List集合:private List<String> names;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入基本数据类型和字符串,写法一:name:属性名 value:属性值-->
<property name="name" value="写法"></property>
<!--注入基本数据类型和字符串,写法二:name:属性名 value:属性值-->
<property name="count">
<value>10</value>
</property>
</bean>
注入对象类型List集合:private List<Student> students1;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象类型List集合,name:属性名 bean:对象-->
<property name="students1">
<list>
<bean class="com.itbaizhan.domain.Student">
<property name="id" value="1"></property>
<property name="name" value="程序员1"></property>
<property name="address" value="北京"></property>
</bean>
<bean class="com.itbaizhan.domain.Student">
<property name="id" value="2"></property>
<property name="name" value="程序员2"></property>
<property name="address" value="上海"></property>
</bean>
</list>
</property>
</bean>
(4)注入Set集合:private Set<Student> students2; // 对象类型Set集合
注入Set集合和List集合大体一样,只是把<List>标签换成<Set>标签
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象类型Set集合,name:属性名 bean:对象-->
<property name="students2">
<set>
<bean class="com.itbaizhan.domain.Student">
<property name="id" value="3"></property>
<property name="name" value="程序员3"></property>
<property name="address" value="北京"></property>
</bean>
<bean class="com.itbaizhan.domain.Student">
<property name="id" value="4"></property>
<property name="name" value="程序员4"></property>
<property name="address" value="上海"></property>
</bean>
</set>
</property>
</bean>
(5)注入Map集合:private Map<String,String> names2; //字符串类型Map集合
private Map<String,Student> students3;// 对象类型Map集合注入简单数据类型Map集合:
private Map<String,String> names2;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入简单数据类型Map集合-->
<property name="names2">
<map>
<entry key="student1" value="bz"></entry>
<entry key="student2" value="sxt"></entry>
</map>
</property>
</bean>
注入对象数据类型Map集合:
private Map<String,Student> students3;
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入对象数据类型Map集合,value-ref:引入定义好的对象值的id值-->
<property name="students3">
<map>
<entry key="student1" value-ref="s1"></entry>
<entry key="student2" value-ref="s2"></entry>
</map>
</property>
</bean>
<bean id="s1" class="com.itbaizhan.domain.Student">
<property name="id" value="1"></property>
<property name="name" value="bz"></property>
<property name="address" value="北极"></property>
</bean>
<bean id="s2" class="com.itbaizhan.domain.Student">
<property name="id" value="2"></property>
<property name="name" value="sxt"></property>
<property name="address" value="上海"></property>
</bean>
(6)注入Properties对象:private Properties properties;//Properties类型
<bean id="studentService" class="com.itbaizhan.service.StudentService">
<!--注入Properties对象-->
<property name="properties">
<props>
<prop key="配置1">值1</prop>
<prop key="配置2">值2</prop>
</props>
</property>
</bean>