前一篇博文将了 IOC 的思想,Spring的一大特性就是对IOC的实现方式和运用,本文主要讲这个。
Spring对IOC的实现思路 和我上一篇的思路基本类似,也是实现IOC的 主流方式,名叫 依赖注入(DI)。网上有很多类似博文去讲 DI、IOC,很容易把人绕晕。不知道这两者有何区别。
IOC: 控制反转的思想,是一种想法和原则,即 希望把 依赖接口的实现类的指向工作的控制权,不要放在调用类(前面一篇博客的Car类)中,而是交由第三方去做(并没有说如何做,怎么做。因为这只是思想,并没有具体到实现方式)。从而去除 调用类和接口实现类的 硬编码耦合。
DI: 是控制反转思想的一种实现思路,即通过 依赖注入的方式,来达到IOC的目的。
Spring就是通过DI的方式来 实现IOC,即Spring框架提供了一个 缓存容器,你能够把很多类的实例事先放入这个 容器中,然后在需要的时候,帮你把调用类的成员变量的实例注入进来。举例如下:
/**
* Car类是一个调用类,其有一个成员变量wheel,依赖于Wheel接口
*/
public class Car {
private Wheel wheel;
public void truckRun(){
wheel.trun();
}
}
public interface Wheel {
void trun();
}
/**
* 前驱轮的实现类
*/
public class PrecursorWheel implements Wheel{
@Override
public void trun() {
System.out.println("precursor trun!");
}
}
/**
* 后驱*的实现类
*/
public class RearWheel implements Wheel{
@Override
public void trun() {
System.out.println("rear trun!");
}
}
Car类的run()方法的执行,是要靠 Wheel的turn()方法。但是 Wheel的turn()方法 能顺利执行,必须要知道 Wheel的实例到底是哪个,在实际需求中,可以是PrecursorWheel的实例,也可以是RearWheel的实例。
到底选择哪个实例呢?我们通过配置的方式告诉 Spring,然后由Spring来帮助我们自动注入,怎么注入呢?
1. 在Wheel的每个实现类上加上 @Service注解,通过value为容器中的实例命名,这样Spring容器在启动时,就会自动构建这些类的实例,然后将这些类的实例保存到Spring容器中。
2. 在Car类wheel成员变量上 加上 @Autowired 注解,通过 @Qualifier注解来指定你想注入哪个实现类,这样Spring会把wheel成员变量指向容器中的目标实例。
代码如下:
/**
* 前驱轮的实现类
*/
@Service(value = "precursor")
public class PrecursorWheel implements Wheel{
@Override
public void trun() {
System.out.println("precursor trun!");
}
}
/**
* 后驱*的实现类
*/
@Service(value = "rear")
public class RearWheel implements Wheel{
@Override
public void trun() {
System.out.println("rear trun!");
}
}
/**
* Car类是一个调用类,其有一个成员变量wheel,依赖于Wheel接口
*/
public class Car {
/**
* 自动注入,并指定wheel是RearWheel类的实例
*/
@Autowired
@Qualifier(value = "rear")
private Wheel wheel;
public void truckRun(){
wheel.trun();
}
}
这时候,你就可以在Car类中随意使用 wheel 对象了,因为Spring已经帮你自动注入了。
我这篇文章并没有去讲,如何构建Spring项目,以及如何配置xml来使得你的注解生效。因为我相信大家多尝试几次,网上找一些教程,就肯定能配置和操作了。
我这篇文章主要是想让大家能直观的 感受一下 Spring对 IOC的支持和实现,从而帮助大家理解 IOC 和 DI的概念。
只有当你真正 理解了 IOC 和 DI :IOC是什么意思?为什么要用它?好处在哪?DI和IOC的关系?
以后的开发中,你才能灵活运用IOC,来帮助你使得你的代码简洁而优雅。
我的理解有错误,或者大家有什么想法,欢迎指正!