什么是IOC
IOC,Inversion of Control,即控制反转,如何理解控制反转,首先先思考以下这四个字,控制、反转,也就是有控制和反转两个概念。
控制:
控制的是什么:对象的创建和管理。
当然这里说的控制的概念是在spring中的体现,在其他场景下可能控制的是其他的资源形式和生命周期
谁控制:
在传统式方下,例如现在有两个类A、B,在A中需要引用到B,则需要在A中new一个B的对象,这里先以伪代码的形式体现:
class A{
B b = new B();
}
也就是说在创建对象的时候,是我们开发人员创建的对象,对象的创建以及管理是都需要开发人员去做的。
在IOC方式下,对象的创建以及管理都是交给IOC容器来完成,开发人员只需要在类中注入需要的对象即可,不需要手动来创建和管理对象。
反转:
这里说到反转的概念,自然而然会想到肯定有正转,那么正转就是上述说的当对对象的创建和管理由开发人员去控制的时候,是属于控制正转。
反转的概念便是当对对象的创建和管理交给IOC容器的时候,就是控制的反转。
所以这里的控制反转也就是对于对象的创建和管理这件事情从开发人员手里转到了IOC容器。
什么会有IOC? IOC解决了什么问题?
举个例子:
现有两个Service,他们都调用了另外一个Service的接口,所以在程序中会有这样的代码:
AService 和BService 都调用CService的接口方法:
class AService{
//这里会new一个CService接口的一个实现
CService cServce = new CServiceImpl();
public void get(){
cService.get();
}
}
class BService{
//这里会new一个CService接口的一个实现
CService cServce = new CServiceImpl();
public void get(){
cService.get();
}
}
class CServiceImpl implement CService{
public void get(){
...
}
}
从以上代码来看,功能实现上没有什么太大问题,但是问题来了,如果原CService接口实现类CServiceImpl不用了,新写了一个实现类叫CServiceNewImpl,这样我们在调用接口的时候,是不是需要到AService、BService中去修改代码分别将实现类修改为
CService cServce = new CServiceNewImpl();
这样其实是很不友好的,如果引用的地方少也就算了,如果项目中大量的用到了这个接口,岂不是要改到怀疑人生。而且我们java开发都是面向接口开发,像这样new一个实现类的形式岂不是面向实现开发了,这也不符合我们开发思想。
所以这时候IOC就能很好的解决我们的问题,怎么解决的呢? 我们使用IOC的时候,是将我们引用的那个对象注入进来即可:
class AService{
CService cService;
}
我们只需要将其接口注入即可,而且注入的也是接口,面向的是接口并非实现,所以也符合我们的开发思想,而且降低了我们对引用对象实现的耦合度。
所以IOC既符合我们的开发思想也在很大程度上降低了对象之间的耦合度。
什么是DI
DI,Dependency Injection,即依赖注入。
依赖注入这里有两个概念,依赖和注入,何为依赖,何为注入,这里可以分为几个问题来思考:
谁依赖谁:对象依赖于IOC容器
注入了什么:对象,一个对象需要引用到另一个对象的时候,可以借助IOC注入到该对象中。
所以依赖注入中,容器会把对象依赖的其他对象注入进去。
IOC和DI区别
IOC不是一种技术体现,而是一种思想,可以应用于不同场景,spring是对IOC思想的一种很好的实现。
IOC是站在对象的角度去描述,而DI是站在容器的角度去描述的。
也可以把IOC理解为是中心思想,核心是为了实现IOC,DI只是一种实现方式罢了。IOC是实现目的,DI是实现手段。