依赖注入和控制反转含义相同,它们是从两个角度描述的同一个概念。
当某个Java实例需要另一个Java实例时,传统的方法是由调用者创建被调用者的实例(例如,使用new关键字获得被调用者实例),而使用Spring框架后,被调用者的实例不再由调用者创建,而是由Spring容器创建,这称为控制反转。
Spring容器在创建被调用者的实例时,会自动将调用者需要的对象注入给调用者,这样,调用者通过Spring容器获得被调用者实例,这称为依赖注入。
依赖注入主要有两种实现方式,分别是属性setter方法注入和构造方法注入。具体介绍如下。
1)属性setter注入
指IoC容器使用setter方法注入被依赖的实例。通过调用无参构造器或无参static工厂方法实例化bean后,调用该bean的setter方法,即可实现基于setter的DI。
2)构造方法注入
指IoC容器使用构造方法注入被依赖的实例。基于构造器的DI通过调用带参数的构造方法实现,每个参数代表一个依赖。
下面通过属性setter注入的案例演示Spring容器是如何实现依赖注入的。具体步骤如下。
1.创建PersonService接口
在springDemo01项目的com.mengma.ioc包下创建一个名为PersonService的接口,该接口中包含一个addPerson()方法,如下所示。
package com.mengma.ioc;
public interface PersonService{
public void addPerson();
}
2.创建接口实现类PersonServicelmpl
在com.mengma.ioc包下创建一个名为PersonServicelmpl的类,该类实现了PersonService接口,如下所示。
packge.com.mengma.ioc;
public class PersonServiceImpl implements PersonService{
//定义接口声明
private PersonDao personDao;
// 提供set()方法,用于依赖注入
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
// 实现PersonService接口的方法
@Override
public void addPerson() {
personDao.add(); // 调用PersonDao中的add()方法
System.out.println("addPerson()执行了...");
}
}
上述代码中,首先声明了personDao对象,并为其添加setter方法,用于依赖注入,然后实现了PersonDao接口的addPerson()方法,并在方法中调用save()方法和输出一条语句。
3.在applicationContext.xml中添加配置信息
在applicationContext.xml配置文件中添加一个<bean>元素,用于实例化PersonServiceImpl类,并将personDao的实例注入到personService中,其实现代码如下。
<bean id="personService" class="com.mengma.ioc.PersonServiceImpl">
<!-- 将personDao实例注入personService实例中 -->
<property name="personDao" ref="personDao"/>
</bean>
4.编写测试方法
在FirstTest类中创建一个名为test2()的方法,编辑后如下所示:
@Test
public void test2() {
// 定义Spring配置文件的路径
String xmlPath = "applicationContext.xml";
// 初始化Spring容器,加载配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
xmlPath);
// 通过容器获取personService实例
PersonService personService = (PersonService) applicationContext
.getBean("personService");
// 调用personService的addPerson()方法
personService.addPerson();
}
5.运行项目并查看结果
使用JUnit测试运行test2()方法,运行成功后,控制台的输出结果如图1所示。
save()执行了...
addPerson()执行了...
从上图的输出结果中可以看出,使用 Spring 容器获取 userService 的实例后,调用了该实例的 addPerson() 方法,在该方法中又调用了 PersonDao 实现类中的 add() 方法,并输出了结果。这就是 Spring 容器属性 setter 注入的方式,也是实际开发中较为常用的一种方式。