在Java中,当某个对象(调用者)需要调用另一个对象(被调用者)时,调用者通常会采用“new 被调用者”
来创建对象,如:
InputStream in = new FileInputStream(file);
但是这种方式不利于项目后期维护。
下图是我理解的传统方法调用对象:
使用Spring框架后,对象的实例不再由调用者来创建,而是由 Spring 容器来创建。
Spring 容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。就相当于在调用者和被调用者之间安排了一个管理员
,调用者和被调用者的关系通过String这个管理员来处理、连接和调用。
从 Spring 容器的角度来看,Spring 容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是 Spring的依赖注入
依赖注入的作用就是在使用 Spring 框架创建对象时,动态地将其所依赖的对象注入 Bean 组件中,其实现方式通常有两种,一种是属性 setter 方法注入
,另一种是构造方法注入
。
属性 setter 方法注入:
指Spring容器使用setter方法注入被依赖的实例。 通过调用无参构造器或无参静态工厂方法实例化Bean后,调用该Bean的setter方法,即可实现基于setter方法的依赖注入。
构造方法注入:
指Spring容器使用构造方法注入被依赖的实例。 基于构造方法的依赖注入通过调用带参数的构造方法来实现,每个参数代表着一个依赖。
我们先创建一个UserDao接口,编写一个say()方法,并创建它的实现类UserDaoImpl:
/*
* UserDao接口
*/
public interface UserDao{
public void say();
}
/*
* 实现类UserDaoImpl
*/
public class UserDaoImpl implements UserDao{
public void say(){
System.out.println("This is UserDao");
}
}
接下来再创建一个UserService接口,以及它的实现类UserServiceImpl:
/*
* UserService接口
*/
public interface UserService{
public void say();
}
/*
* 实现类UserServiceImpl
*/
public class UserServiceImpl implements UserService{
//声明UserDao属性
private UserDao userDao;
//添加UserDao属性的setter方法,用于实现依赖注入
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void say(){
this.userDao.say();
System.out.println("This is UserService");
}
}
在 UserService中我声明了 userDao属性,并且添加它的setter方法。之后在 applicationContext.xml
中创建一个id为userService的Bean,用来实例化UserService类的信息,并将userDao的实例注入到userService中。
<property>
是元素的子元素,它用于调用Bean 实例中的setUserDaoO方法完成属性赋值,从而实现依赖注入。
<?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-4.3.xsd">
<!-- 将指定类配置给Spring -->
<bean id="userDao" class="com.gx.ioc.impl.UserDaoImpl" />
<bean id="userService" class="com.gx.ioc.impl.UserServiceImpl">
<!-- 将id为userDao的Bean实例注入到userSerice实例中 -->
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
然后就可以创建一个Test类来测试我们的代码了
public class TestDI {
public static void main(String[] args) {
//初始化spring容器
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//通过容器获取UserService实例
UserService userService = (UserService) applicationContext.getBean("userService");
//调用实例中的say()方法
userService.say();
}
}
运行结果如下:
使用Spring 容器通过UserService实现类中的sayO方法,调用了UserDao实现类中的sayO方法,并输出了结果。 这就是Spring容器属性setter注入的方式,也是实际开发中最为常用的一种方式。