java学习笔记之Spring依赖注入和控制反转

来源:互联网 发布:主播过度劳累猝死知乎 编辑:程序博客网 时间:2024/05/17 01:59
相信对于很多学习spring框架的朋友,控制反转(Ioc)和依赖注入(Di)这两个概念并不陌生,但很多朋友可能总对着两个概念的理解含糊不清,网上很多资料阅读了之后还是让人云里雾里,本篇就是笔者在使用和学习过程中对这个两个概念的理解和心得。

1. 引言

在之前不使用spring框架的传统j2ee开发中,如果一个类中依赖另一个类的方法去实现处理一个功能,那程序员需要手动在这个类中采用new关键字去实例化这个类,然后调用这个实例化后的的类的对象的方法,这样在项目不大的情况下尚且可以,如果项目很大,类很多,那么势必类和类之间依赖关系会很多很复杂,如果我们因为业务需要修改了一个类的名称或者类中的方法,那么所以对这个类有依赖关系的类我们都必须一一去修改,这样让类的依赖关系管理起来很复杂很麻烦,严重降低了开发效率,那么有没有什么更好的方法呢?

2. 通俗的理解控制反转和依赖注入

上面的问题如何解决呢,我们可以结合现实中的例子去模拟下,我们如果要找女朋友怎么找,通常我们会在学校中,工作中,生活中,甚至大街上认识遇见能让我们一见钟情萌生爱意的女生,然后我们会主动和她们接触交流,想尽办法让她们对我们有好感,然后求爱求婚最终走到一起,这就好比我们程序员在一个类中要调用另一个类的方法一样,我们必须自己去new(去找女朋友,去示爱,去求爱)一个类的实例;同样在现实中有婚介所这种机构,我们把我们的信息登记和要找的异性的信息登记在婚介所,如果我们需要找老婆了,给婚介所说一声,他们会根据我们所登记的信息去找合适的异性信息给我们,而控制反转就是原来实例对象的控制权在我们手里,而现在交由spring容器去实例化(类比交友婚介所找老婆),控制权反转了,而依赖注入就是spring容器根据我们配置的依赖信息去帮我们实例化指定类然后将实例化后的对象注入到我们的类中(类比我们在婚介所登记的要找的异性信息)。

3. 控制反转(Ioc)是什么

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

传统的“正转控制”类的实例化模式图

Spring Ioc

Spring的“控制反转”类的实例化模式图

Spring IOC

4. 控制反转Ioc能做什么

简单来说控制反转不是一种技术,而是一个编程开发思想,由原来的程序是我开发的,我就是老大,我想在哪里在什么时候实例化一个类我就可以,变为了现在将实例化的控制权反转给了spring容器,这样使得程序的整体结构更灵活,降低了类与类之间耦合性,这样有利于提高开发效率,提高代码复用性,也使测试变得简单。

5. 依赖注入(DI)

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工作只是在spring的框架中堆积木而已。

6. 控制反转和依赖注入的关系

DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

●谁依赖于谁:当然是应用程序依赖于IoC容器;

●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;

●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

看过很多对Spring的Ioc理解的文章,好多人对Ioc和DI的解释都晦涩难懂,反正就是一种说不清,道不明的感觉,读完之后依然是一头雾水,感觉就是开涛这位技术牛人写得特别通俗易懂,他清楚地解释了IoC(控制反转) 和DI(依赖注入)中的每一个字,读完之后给人一种豁然开朗的感觉。我相信对于初学Spring框架的人对Ioc的理解应该是有很大帮助的。

0 0
原创粉丝点击