依赖注入(DI)
DI和IoC的含义相同,两者是从两种角度描述同一个概念。
理解:
当某个Java对象需要调用另一个Java对象(被依赖对象)时,在传统模式下,调用者会用“new 被调用者“的方式来创建对象,这种方式增加的耦合性,不利于后期项目的维护和升级。
使用Spring框架后,对象的实例由Spring容器创建,容器会负责控制程序之间的关系,不是由调用者的程序代码直接控制。控制权转移到了Spring容器,控制发生了反转,这就是Spring的控制反转(IoC)。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的DI。
依赖注入的实现方式:
依赖注入的作用:在使用Spring框架创建对象时,动态地将其所依赖的对象注入Bean组件中。
- 属性setter方法注入:IoC容器使用setter方法注入被依赖的实例。通过调用无参构造方法或无参静态工厂方法实例化Bean后,调用该Bean的setter方法。
- 构造方法注入:IoC容器使用构造方法注入,通过调用带参数的构造方法来实现,每个参数代表着一个依赖。
以setter方法注入的方式做一个Test:
所需包:
编写接口UserService,在接口中添加一个方法:say()
package com.itheima.ioc; public class UserServiceImpl implements UserService{ //声明UserDao属性 private UserDao userDao; //添加UserDao属性的setter方法,用于实现依赖注入 public void setUserDao(UserDao userDao){ this.userDao = userDao; } @Override public void say() { //调用UserDao中的say()方法,并执行输出语句 this.userDao.say(); System.out.println("userService say hello World!"); // TODO Auto-generated method stub } }
在配置文件applicationContext.xml中创建一个userService的Bean,用于实例化UserServiceImpl的信息,并将userDao的实例注入到userService中
<!-- 添加一个UserService的实例 --> <bean id="userService" class="com.itheima.ioc.UserServiceImpl"> <!-- 将id为userDao的bean实例注入userService实例中 --> <property name="userDao" ref="userDao"></property>
Test类
package com.itheima.ioc; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestDI { public static void main(String[] args) { //初始化Spring容器,加载配置文件 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过容器获取UserService实例 UserService userService = (UserService) applicationContext.getBean("userService"); userService.say(); } }