根据Martin Fowler所写的论文,控制反转是程序控制流反转的原理:由外部源(框架、服务、其他组件)控制程序流,而不是由程序员控制程序流。就像我们把一个东西插入另一个东西。他提到了一个关于EJB 2.0的例子:
例如,会话Bean接口
定义ejbRemove, ejbPassivate
(存储到二级存储),以及
ejbActivate(从被动恢复
状态)。你不能控制时间
这些方法被调用,只是什么
他们做的事。集装箱召唤我们,我们
别这么说。
这就导致了framework和library的区别:
控制反转是一个关键的部分
框架与框架的区别是什么
图书馆。图书馆本质上是一个
一组你可以调用的函数,
这些日子通常组织成
类。每次调用都要做一些工作
将控制权返回给客户端。
我认为,DI是IOC的观点,意味着对象的依赖关系是倒置的:而不是它控制自己的依赖关系、生命周期……其他东西可以帮你。但是,正如你告诉我的DI by hands, DI不一定是IOC。我们仍然可以有DI,没有IOC。
然而,在本文中(来自pococapsule, C/ c++的另一个IOC框架),它指出,由于IOC和DI, IOC容器和DI框架要比J2EE优越得多,因为J2EE将框架代码混合到组件中,因此它不是普通的旧Java/ c++对象(POJO/POCO)。
依赖注入模式以外的控制反转容器(存档链接)
附加阅读,了解旧的基于组件的开发框架的问题,这导致了上面的第二篇论文:为什么和什么反转控制(档案链接)
我的问题:IOC和DI到底是什么?我很困惑。基于pococapsule, IOC不仅仅是对象或程序员与框架之间控制的反转。
//ICO, DI,10年前,他们是这样的:
public class AuditDAOImpl implements Audit{
//dependency
AuditDAO auditDAO = null;
//Control of the AuditDAO is with AuditDAOImpl because its creating the object
public AuditDAOImpl () {
this.auditDAO = new AuditDAO ();
}
}
现在有了Spring 3,4或最新版本,如下图所示
public class AuditDAOImpl implements Audit{
//dependency
//Now control is shifted to Spring. Container find the object and provide it.
@Autowired
AuditDAO auditDAO = null;
}
总的来说,控件从耦合代码的旧概念倒向了使对象可用的Spring等框架。据我所知,这就是IOC和依赖注入我们使用构造函数或setter将依赖对象注入到另一个对象。注入基本上意味着将它作为参数传递。在spring中,我们有基于XML和注释的配置,我们定义bean对象,并通过构造函数或setter注入样式传递依赖对象。
控制反转(IoC)模式是关于提供任何类型的回调,它“实现”和/或控制反应,而不是我们自己直接操作(换句话说,反转和/或重定向控制到外部处理程序/控制器)。
例如,不是让应用程序调用库(也称为工具包)提供的实现,而是库和/或框架调用应用程序提供的实现。
依赖注入(DI)模式是IoC模式的一个更具体的版本,其中实现通过构造函数/设置器/服务查找传递到对象中,对象将“依赖”这些以正确地行为。
每个DI实现都可以被认为是IoC,但不应该称之为IoC,因为实现依赖注入比实现回调更难(不要使用通用术语“IoC”来降低产品的价值)。
例如,不使用DI的IoC将是Template模式,因为实现只能通过子类化来更改。
依赖注入框架被设计为使用依赖注入,并且可以定义接口(或Java中的注释)以方便在实现中传递。
IoC容器是可以在编程语言之外工作的依赖注入框架。在某些情况下,您可以在元数据文件(例如XML)中配置要使用的实现,这是侵入性较小的。有一些可以做IoC,这通常是不可能的,比如在切入点注入实现。
参见Martin Fowler的文章。