DI (spring的依赖注入)
/**
* 森林探险任务
*/
public class ForestTask {
public ForestTask() {
}
}
/**
* 骑士
*/
public class Knight {
private ForestTask task;
public Knight() {
task = new ForestTask();
}
public static void main(String[] args) {
Knight knight = new Knight();
System.out.println(knight.task.getClass());
}
}
没有使用DI前,骑士需要自己初始化冒险任务,如果以后不只有森林探险(ForestTask),还有
海上探险(SeaTask),空中探险(SkyTask),骑士都需要找到相应的任务类进行初始化。
问题:骑士的实现与任务的具体实现耦合在一起,骑士必须知道每种探险任务的具体实现类,
以使自己能初始化探险任务进行下去。
/**
* 探险任务接口
*/
public interface ITask {
}
/**
* 森林探险任务
*/
public class ForestTask implements ITask {
public ForestTask() {
}
}
/**
* 骑士
*/
public class Knight {
public Knight() {
}
private ITask task;
public void setTask(ITask task) {
this.task = task;
}
public static void main(String[] args) {
Knight knight = new Knight();
knight.setTask(new ForestTask());
System.out.println(knight.task.getClass());
}
}
上面的代码做了改进,初始化冒险任务的方式改了一下,主动把冒险任务交给骑士,骑士只需要执行就可以了,而不再需要主动去创建冒险任务,而且骑士面对的是探险任务的统一接口,而不是某种具体的冒险任务实现类。
骑士类面对是接口不是具体实现类,这正是体现了java的面向接口的编程思想,当具体的冒险任务实现类不断继承任务接口时,骑士类可以进行更多种类的冒险任务而不需要进行修改,骑士类可以专注在自己的业务逻辑中。
而spring中的DI只是通过bean的配置实现了具体实现类的注入,从本质上说,spring的依赖注入并不是新的思想,只是说从框架上强制使用了java的面向接口的编程思想,使得代码松散不耦合。
当了解到DI的本质时,对于什么是DI,为什么要用DI,怎样用DI这三个问题,估计你心里应该有个答案了。