【Spring】IOC
浅谈IOC
IOC的理论背景

图1:传统系统中,对象之间相互引用的一幅图,在采用面向对象方法设计的软件系统中,它的底层的实现都是由n个对象所组成的,所有的对象通彼此之间的合作最终实现系统的业务逻辑,如果我们打开机械式手表的后盖,我们就会看到与图1类似的清形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。这些齿轮相互耦合在一起,共同完成某项任务。在这样的齿轮组中,如果有一个齿轮出现一个问题,可能会影响到整个齿轮组的正常运转,齿轮组齿轮间的耦合关系与软件系统中对象之间的耦合关系非常相似。随着系统规模变大,对象之间依赖关系越来越复杂,架构师和设计师对系统的设计和分析面临更大的挑战,对象之间的耦合度过高的系统,必然会出现牵一发而动全身的情形,降低系统之间、模块之间、对象之间的耦合度是软件工程追求的目标。IOC理论的提出,就是为了解决对象之间耦合度过高的问题,实现对象之间的解耦。

图2 解耦的过程
IOC理论提出的观点大致是这样的:借助于第三方来实现对具有依赖关系的对象之间的解耦,对象之间没有了耦合关系。由于引进了第三方IOC容器,使得对象A、B、C、D之间没有了耦合关系,齿轮之间的传动全部依靠了第三方,全部对象的控制权全部交给了第三方IOC容器,IOC容器成了整个系统的关键核心,它起到了一种凝合剂i的作用,把系统中的所有对象凝合在一起发挥作用。

图3 理想的系统
这四个对象之间彼此毫无联系,这样在实现A的时候,无需去考虑B、C、和D,对象之间的依赖关系降低到了最低程度。 参与开发的每一位成员,只要实现自己的类就好了,跟别人没有任何关系。我们再来看看,控制反转到底为什么取这个名字。
软件系统在没有引入IOC容器之前,就像图1所示,对象A 依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须去创建对象B,或者是使用已经创建的B,无论是创建还是使用对象B,控制权全部都在自己手上,在软件系统引入了IOC以后,这种情形就完全改变了,如图2所示,由于IOC容器的加入,对象A和对象B失去了直接的联系,所以当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B,注入到对象A所需要的地方,通过前后的对比,不然看出,对象A获得依赖对象B的过程, 由主动行为变为了被动行为,控制权颠倒过来了,这个就是控制反转的名称的由来。哪些东西被反转了?获得依赖对象的过程被反转。获得依赖对象的过程由自身的管理变为了由IOC容器主动的注入。依赖注入(DI)其实是实现控制反转(IOC)的方式。
依赖注入DI
IOC的另外的名字叫做依赖注入(DI),所谓的依赖注入,就是由IOC容器再运行期间动态地将某种依赖注入到对象之中。所以,依赖注入(DI)和控制反转(IOC)是从不容的角度描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

图4 电脑 和 外设都是对象,人起到IOC容器的作用
IOC容器就像一个对象制造工厂,你需要什么,它就会传送给你。你直接使用就可以,再也不用关心你是用的东西是如何生成的,最后如何销毁的,这一切都有IOC容器管理。再传统的实现中, 由程序内部代码来控制组件之间的关系,我们经常使用new关键字来实现两个组件之间关系的组合,这种方式会造成组件之间耦合,IOC很好的解决了这种问题,它将 实现组件间的关系 从程序内部提炼到了外部容器,也就是说由容器再运行期间将组件间的某种依赖关系动态地注入到组件中。
IOC好处
IOC在编程过程中不会对业务对象构成很强的侵入性,使用IOC之后,对象具有更好的可实行性,可重用性和可扩展性:
- 降低组件之间的耦合度
- 提高开发效率和产品质量
- 同意标准,提高模块的复用性
- 模块具有热插拔特性
举个例子:使用USB外部设备比使用电脑内置硬盘带来什么好处呢?第一:USB设备在插入主机之前,与电脑主机没有任何关系,只有被连接在一起后,才有关系,所以无论任何一方发生问题,都不会影响另一方,这在软件工程中就叫做可维护性,非常便于单元测试、调试程序和诊断故障。代码中的每个class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合、无耦合带来的好处。 第二 USB和主机之间的无关性还带来了另外一个好处,生产USB和生产电脑的厂商可以是完全互不相干的两个人,他们各干各事,唯一需要遵守的是USB接口的标准,这种特性体现在软件开发过程中,好处很大,每一个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用关心其他人的工作进度。你的任务可以单独测试也不依赖于别人的组件,每个人分工明确,效率提高。第三:提高了模块的复用性。同一个USB外部设备,可以插到任何支持USB的设备,可以插到电脑主机,可以插到DV机,USB外部设备可以被反复利用。我们可以把具有普遍性的、常用的组件独立出来,反复利用到项目中的其他部分或者其他项目,当然这也是面向对象的基本特征。第四:模块具有热插拔特性。IOC生成对象的方式,转为外置方式,也就是把对象生成放到了配置文件进行定义,这样当我们更换一个实现子类将会变得更加简单,只要修改配置文件就可以,完全具有热插拔的特性。(热插拔(hot-plugging或Hot Swap)即带电插拔,热插拔功能就是允许用户在不关闭系统,不切断电源的情况下取出和更换损坏的硬盘、电源或板卡等部件,从而提高了系统对灾难的及时恢复能力、扩展性和灵活性等,例如一些面向高端应用的磁盘镜像系统都可以提供磁盘的热插拔功能。)
IOC的通俗理解如下
- IOC控制反转:说的是创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是你在XML文件当中的控制,侧重于原理
- DI依赖注入:说的是再创建对象实例时,为这个对象注入属性值或其他对象实例,它侧重于实现。
【Spring】IOC的更多相关文章
- 【Spring】IOC容器注解汇总,你想要的都在这儿了!!
		写在前面 之前,我们在[Spring]专题中更新了不少关于Spring注解相关的文章,有些小伙伴反馈说,看历史文章的话比较零散,经常会忘记自己看到哪一篇了.当打开一篇新文章时,总感觉自己似乎是看到过了 ... 
- 【Spring】 IOC Base
		一.关于容器 1. ApplicationContext和BeanFactory 2. 配置文件 XML方式 Java-configuration 方式 @Configuration 3. 初始化容器 ... 
- 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )
		前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ... 
- 【Spring】IoC容器 - 依赖来源
		前言 上一篇文章已经学习了[依赖注入]相关的知识,这里详细的介绍一下[依赖来源]. 依赖来源 我们把依赖来源分为依赖查找的来源和依赖注入的来源分别讨论. 依赖查找的来源 1. Spring BeanD ... 
- 【Spring】IoC容器 - 依赖注入
		前言 上一篇文章已经学习了[依赖查找]相关的知识,这里详细的介绍一下[依赖注入]. 依赖注入 - 分类 因为自己是基于小马哥的脉络来学习,并且很认可小马哥梳理的分类方式,下面按照小马哥思想为[依赖注入 ... 
- 【Spring】IoC容器 - 依赖查找
		前言 上一篇文章已经学习了[IoC的主要实现策略]有2种: 1.依赖查找 2.依赖注入 这里稍加详细的介绍一下依赖查找 1.依赖查找的方式 依赖查找的方式可以以多种维度来划分: 1.按名称/类型/注解 ... 
- 【Spring】IoC概述
		Spring框架的核心概念--IoC IoC IoC是Inversion of Control的简写,翻译成汉语就是"控制反转".IoC并不是一门技术,而是一种设计思想,在Spri ... 
- 【Spring】AOP注解方式实现机制
		一.概述 二.@EnableAspectJAutoProxy 注解分析 三.分析AnnotationAwareAspectJAutoProxyCreator 四.执行流程 1. registerBea ... 
- 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程
		原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ... 
随机推荐
- 50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】
			如果你使用的是spring boot 1.4.0版本的话,那么你可能需要配合以下文章进行学习 90.Spring Boot 1.4 使用log4j错误[从零开始学Spring Boot] Log4j是 ... 
- - > 并查集详解(第二节)
			以下是并查集思路详解: 一:概念 并查集处理的是“集合"之间的关系.当给出两个元素的一个无序数对(a,b)时,需要快速“合并”a和b分别所在的集合,这期间需要反复“查找”某元素所在的集合.“ ... 
- vue2源码浏览分析02
			1.组件初始化方法 init Vue.prototype._init = function (options) { /* istanbul ignore if */ if ("develop ... 
- 再次讨论javascript 中的this
			原文: http://www.jb51.net/article/77519.htm 核心总结: 1.不论函数在哪里被调用,只要没有指定调用方,则this都指向window.指定了调用方,就指向调用方. ... 
- DIY.NETORM框架——总体分析
			一.故事 近些年一直开发MIS系统,用过PB,VB,C# .如今学了半年的java,早先听人说,.NET和 java一直就是互相借鉴.一起升级.都是为了让程序开发趋于简单,高校,而这不可避免就肯定用 ... 
- datatables接口
			/*资源表格接口*/ var dataTableHeader=function(elem,unSorts,defaultSort,screens,status,toggleVis,ipAddress, ... 
- iOS中的成员变量,实例变量,属性变量
			在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyV ... 
- Codeforces 91C Ski Base 加边求欧拉回路数量
			题目链接:点击打开链接 题意: 给出n个点m条无向边的图 開始图里没有边.每次加一条边,然后输出图里欧拉回路的条数. 思路: We will count the number of ski bases ... 
- addSubview和insertSubview 区别
			子视图是以栈的方式存放的. 每次addsubview时都是在最后面添加. 每次在addsubview前和addsubview后可以看看[self.view.subViews count]: 你看看你 ... 
- error: 'Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)'
			[root@luozhonghua ~]# /usr/bin/mysqladmin -u root password 'aaaaaa' /usr/bin/mysqladmin: connect t ... 
