依赖注入
依赖注入是为了解决紧耦合问题而产生的一种技术,紧耦合的代码难以测试、难以复用、难以理解,当程序出现bug时,修复bug经常会产生连锁反应,但是,一定程度的耦合又是必须的,完全没有耦合的代码什么也做不了。所以一种比较好的方案就是,将依赖关系交给第三方组件来描述。
通过DI,对象的依赖关系将有系统中负责协调各对象的第三方组件在创建对象的时候设定。例如,在Spring中可以通过编写XML来描述这种关系。
示例(构造器注入)
程序清单
- Knight.java – 接口
- Quest.java – 接口
- BraveKnight.java – 类
- SlayDragonQuest.java – 类
- KnightMain.java – 程序入口
- springContext.xml --描述依赖关系的配置文件
Knight.java
public interface Knight {
/**
* 执行请求
*/
public void embarkOnQuest();
}
Quest.java
public interface Quest {
/**
* 执行
*/
void embark();
}
BraveKnight.java
public class BraveKnight implements Knight{
// 请求接口--泛指某一种请求
private Quest quest;
/**
* 有参构造器 -- 在构造对象的时候将某种请求传递过来,
* 这里就是一个典型的构造器注入示例
* @param quest
*/
public BraveKnight(Quest quest){
this.quest = quest;
}
/**
* 根据请求的响应动作
*/
public void embarkOnQuest(){
quest.embark();
}
}
SlayDragonQuest.java
public class SlayDragonQuest implements Quest{
private PrintStream stream;
/**
* 有参构造器 -- 与BraveKnight类似也是通过构造器来注入的
* @param stream
*/
public SlayDragonQuest(PrintStream stream){
this.stream = stream;
}
/**
* 执行的动作
*/
@Override
public void embark() {
stream.println("Embarking on quest to slay the dragon!");
}
}
依赖关系的配置
springContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id = "kight" class = "com.css.test.spring.BraveKnight">
<constructor-arg ref = "quest" />
</bean>
<bean id = "quest" class = "com.css.test.spring.SlayDragonQuest">
<constructor-arg value="#{T(System).out}"/>
</bean>
</beans>
注:我这里所有的类都放在了com.css.test.spring的包下了,这个路径可以根据喜好任意指定
KnightMain.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class KnightMain {
/**
* 程序入口
* @param args
*/
public static void main(String[] args) {
// 读取配置文件,从而获得依赖关系
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springContext.xml");
// 通过配置文件配置的依赖关系,构造一个knight的对象
Knight knight = context.getBean(Knight.class);
// 执行方法
knight.embarkOnQuest();
// 关闭context
context.close();
}
}
测试
运行KnightMain类,可以获得如下结果。
注意事项
如果在读取配置文件的时候直接使用相对路径不能读取到文件可以在BuildPath配置一下相关依赖关系
然后将配置文件所在的文件夹添加过来eclipse就可以找到了。