【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 ...
随机推荐
- JavaScript保留关键字(全)
JavaScript 标准 所有的现代浏览器已经完全支持 ES5(ECMAScript 5). JavaScript 保留关键字(keyword) Javascript 的保留关键字(标识符)不可以用 ...
- Maven学习总结(31)——Maven坐标详解
Maven的一个核心的作用就是管理项目的依赖,引入我们所需的各种jar包等.为了能自动化的解析任何一个Java构件,Maven必须将这些Jar包或者其他资源进行唯一标识,这是管理项目的依赖的基础,也就 ...
- HDU 1081 DP找最大和的矩阵
题目大意: 在一个给定的大矩阵中找一个小型的矩阵,使这个矩阵中的元素和最大 可以先来看下面这个问题: 原来有做过在一个给定的数字序列中找一个最大和子序列,核心代码如下: ]; ]; ; ; int r ...
- poj 3237 树链剖分模板(用到线段树lazy操作)
/* 本体在spoj375的基础上加了一些操作,用到线段树的lazy操作模板类型 */ #include<stdio.h> #include<string.h> #includ ...
- node.js 利用流实现读写同步,边读边写
//10个数 10个字节,每次读4b,写1b let fs=require("fs"); function pipe(source,target) { //先创建可读流,再创建可写 ...
- [bzoj2038][2009国家集训队]小Z的袜子(hose)_莫队
小Z的袜子 hose 2009-国家集训队 bzoj-2038 题目大意:给定一个n个袜子的序列,每个袜子有一个颜色.m次询问:每次询问一段区间中每种颜色袜子个数的平方和. 注释:$1\le n,m\ ...
- 项目中应用到的框架和技术之一——Materialize
一群做C++的老伙计搞前端开发,徒手写html和css应该会折寿..在网上找了半天,Materialize算是用起来很方便的一款前端界面框架.Google的Material Design看起来感觉还是 ...
- Java Web开发基础(1)-Servlet
概述 Servlet技术是对webserver的扩展,要理解这个,可能先了解一下什么是Webserver以及它的功能,特别是它的不足是非常有帮助的,可參考:点击打开链接.另外.Servlet也是一个用 ...
- 四:Java之字符串操作String、StringBuffer和StringBuilder
string是我们经经常使用到的一个类型,事实上有时候认为敲代码就是在重复的操作字符串,这是C的特点,在java中.jdk非常好的封装了关于字符串的操作.三个类String .StringBuffer ...
- 关于C语言指针的一些新认识(1)
Technorati 标签: 指针,数组,汇编,C语言 前言 指针是C语言的精华,但我对它一直有种敬而远之的感觉,因为一个不小心就可能让你的程序陷入莫名其妙的麻烦之中.所以,在处理字符串时,我总是能用 ...