什么是控制反转和依赖注入?

Spring Framework的核心是基于控制反转的原理。 IoC是一种技术外部化组件依赖关系的创建和管理。 考虑一个类的例子Foo依赖于类Bar的实例来执行某种处理。 传统上,Foo创造了一个Bar的实例使用new运算符或从某种工厂类中获取。 使用IoC方法,Bar(或子类)的实例在运行时由一些外部进程提供给Foo。 这个行为,在运行时注入依赖项,导致IoC被Martin Fowler重命名为更具描述性的依赖注入(DI)。Spring的DI实现基于两个核心Java概念:JavaBeans和接口。 当你使用Spring作为DI提供程序,您可以灵活地在您的内部定义依赖项配置应用程序以不同的方式(例如,XML文件,Java配置类,您的应用程序中的注释)代码,或新的Groovy bean定义方法)。 JavaBeans(POJO)为其提供标准机制创建可以通过多种方式配置的Java资源,例如构造函数和setter方法。

接口和DI是互利的技术。清晰的设计和编码接口的应用程序使得应用程序变得灵活,但是将使用接口设计的应用程序相当高,给开发人员增加了额外的编码负担。通过使用DI,您可以减少在应用程序中使用基于接口的设计所需的代码量几乎为零。同样,通过使用接口,你可以充分利用DI,因为你的豆子可以利用任何接口实现来满足它们的依赖性。接口的使用也允许Spring利用JDK动态代理( Proxy模式),为横切关注点提供强大的概念,如AOP。在DI的上下文中,Spring更像一个容器,而不是一个框架——提供了的实例应用程序类具有他们需要的所有依赖项,但是它以一种更少侵扰的方式这样做。使用DI的Spring只依赖于在你的类中遵循JavaBeans命名约定——没有可继承的特殊类别,也没有可遵循的专有命名方案。如果有的话在使用DI的应用程序中,唯一的改变是在JavaBeans上公开更多的属性,因此允许在运行时注入更多的依赖项。

依赖注入的演变

在过去的几年里,由于Spring和其他DI框架的普及,DI已经获得了广泛的应用Java开发人员社区的接受度。 与此同时,开发人员确信使用DI是应用程序开发的最佳实践,使用DI的好处也很好理解。当Java Community Process(JCP)采用JSR-330时,DI的受欢迎程度得到了认可(2009年的依赖注入)JSR-330已经成为正式的Java规范请求,并且作为您可能期望,规范领导者之一是Spring Johnson的创始人Rod Johnson。在JEE 6中,JSR-330成为整个技术堆栈中包含的规范之一。 同时,EJB体系结构(从3.0版开始)也得到了极大的改进; 它采用了DI模型为了简化各种Enterprise JavaBeans应用程序的开发。

 •减少代码冗余:DI的最大优点之一是它具有显着的能力减少你必须编写的代码量来粘合你的组件一起申请。 通常这段代码是微不足道的,因此创建依赖包含只需创建一个对象的新实例。 但是,冗余代码可以得到相当的当您需要在JNDI存储库中查找依赖项时或者在需要时查找不能像远程资源那样直接调用依赖项。 在在这些情况下,DI可以通过提供自动JNDI查找来真正简化冗余代码和远程资源的自动代理。

•简化应用程序配置:通过采用DI,您可以大大简化配置应用程序的过程。 您可以使用各种选项进行配置那些可注入其他类的类。 您可以使用相同的技术为注入适当的“注入器”表达依赖性要求bean实例或属性。 此外,DI使交换一个更简单为另一个人实施依赖。 考虑你有一个案例DAO组件,对PostgreSQL数据库执行数据操作您想要升级到Oracle。 使用DI,您可以简单地重新配置相应的依赖于业务对象来使用Oracle实现而不是PostgreSQL之一。

•能够在单个存储库中管理公共依赖项:使用传统的公共服务的依赖管理方法 - 例如,数据源连接,事务和远程服务 - 您创建实例(或查找来自某些工厂类的你需要它们的依赖项依赖类)。 这将导致依赖关系在各个类中传播您的应用程序,并更改它们可能会有问题。 当你使用DI时,所有的有关这些公共依赖项的信息包含在单个存储库中,使依赖关系的管理更简单,更不容易出错。

•提高可测试性:当您为DI设计类时,可以实现轻松替换依赖项。 当您测试时,这尤其方便应用。 考虑执行一些复杂处理的业务对象; 对于其中一部分,它使用DAO访问存储在关系数据库中的数据。 为了你的测试,你对测试DAO不感兴趣; 你只是想测试业务对象有各种数据集。 在传统方法中,业务对象是负责获取DAO本身的实例,您很难进行测试这,因为您无法使用模拟轻松替换DAO实现返回测试数据集的实现。 相反,你需要确保您的测试数据库包含正确的数据并使用完整的DAO实现为了你的测试。 使用DI,您可以创建DAO对象的模拟实现返回测试数据集,然后您可以将其传递给业务对象用于检测。 可以扩展此机制以测试应用程序的任何层并且对于测试可以创建mock的Web组件特别有用HttpServletRequest和HttpServletResponse的实现。

•培养良好的应用程序设计:DI的设计通常意味着设计对接口。 一个典型的注入式应用程序设计为所有主要组件被定义为接口,然后是具体的实现使用DI容器创建并连接这些接口。 这种在DI和基于DI的容器出现之前,Java中的设计是可行的Spring,但是使用Spring,你可以免费获得大量的DI功能能够专注于构建应用程序逻辑,而不是支持它的框架

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章