当前位置: 首页 > 编程日记 > 正文

5 分钟一次理解 Spring IOC !

今天我们分析一下 spring 的 IOC,梳理一下 IOC 和 DI 的概念与原理。在网上看到开涛有篇文章写的不错,提取其中一部分精华内容并做一些解读。

1.1.IOC是什么?

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建。

解读:

提到控制就要理解控制的含义,控制就是对象的创建、初始化、销毁。创建对象,原来是 new 一个,现在给 Spring 容器创建了;对象初始化,比如 A 依赖 B,原来是我们通过构造器或者 setter 方法赋值,现在给 Spring 容器自动注入了;销毁对象,原来是我们直接赋值 null 或者做一些销毁操作,现在给 Spring 容器管理生命周期负责销毁。明白了吧,IOC 解决了繁琐的对象生命周期的操作,解耦了我们的代码。

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

解读:

反转的是什么?反转的是控制权。前面提到 Spring 控制了对象的生命周期,那么对象的控制就完全脱离了我们的控制,交给了 Spring。这个反转是指,我们由对象的控制者变成了 IOC 的被动接受者。我们无法决定对象生命周期的任何一个阶段,最多是借助于 Spring 的扩展机制做一些微小的动作,我们甚至无法预判依赖的对象真正被注入的是哪一个。反转好比你家的机器人决定了你的生活节奏,必须听他的。

1.2.IOC能做什么?

IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们设计出松耦合、更优良的程序。把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

解读:

借助 IOC 容器完美解决了耦合问题,甚至可以让八竿子打不着的类型产生注入关系。比如二方包 a 里面有个类型 A1,三方包 b 里面有个类型 B1,这两个都是 readOnly 的,你不可能去创建或修改内部的依赖。但是借助于 IOC,可以把我们自己的类 C1 注入进去,让 A1、B1 依赖于 C1,从而改变二方包的行为。这也是大型企业级开发中 IOC 比较常见的用法。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

解读:

在 IOC 模式下,设计流程变成了真正的无关业务完全独立的流程化设计。你只需要设计良好的流程和依赖,定义出需要什么,然后把控制权交给 Spring 即可。Spring 给你什么对象,你就用什么对象,不要对对象做任何的假设,也不要期待对象有什么特性,只需要等待 Spring 提供对象即可。控制反转就像乔布斯的理念,我告诉你你需要什么。

1.3.IOC和DI

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

解读:

依赖注入是一种实现,而 IOC 是一种设计思想。从 IOC 到 DI,就是从理论到了实践。你把依赖交给了容器,容器帮你管理依赖,这就是依赖注入的核心。越是大型的项目,越难以管理依赖关系,开发工作逐渐变化为一个个节点的开发,而这些节点通过依赖注入关联起来。依赖注入降低了开发的成本、提高了代码的复用率、提高了软件的灵活性,也给软件开发带来了挑战,你根本不知道运行时容器会给你什么。

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

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

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

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

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

解读:

DI 即依赖注入,重点就在于 “依赖”、“注入” 两个概念。什么是依赖?对象运行所需要的外部的数据、资源就是依赖,没有这些东西对象不能完成业务处理,必须拿到才能运行。什么是注入?注入这个词真的很形象,就像打针一样,从外部注入到内部,容器加载了外部的文件、URL、配置和对象然后把这些数据、对象按需注入给对象。

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊,所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

解读:

IOC 和 DI 是同一个概念的不同角度描述,但实际上又是有区别的。IOC 强调的是容器和对象的控制权发生了反转,而 DI 强调的是对象的依赖由容器进行注入,大部分情况下说两者相同也不算错。 但是广义上 IOC 是一种软件开发模式,也就是说还可以通过别的方式实现,而 DI 只是其中一种,Spring 选择了 DI 从而使 DI 在 Java 开发中深入人心。

关注公众号“程序之心”(ID:chengxuzhixin),每天给你诚意满满的干货!

转载于:https://juejin.im/post/5bf7ff04f265da6179747ab7

相关文章:

工作两年的编程感想

2019独角兽企业重金招聘Python工程师标准>>> 工作已有两年了,两年不长也不短了,程序员的辛酸苦乐也都体验了一些,故写此博客既为留念,也为接下来的两年留下一个参考点。 首先需要声明的是,本人的工作是Java…

微服务重构心得

现在都在做微服务,看起来就是做服务拆分比较简单,但是实际上真正重构起来又遇到许许多多的问题。 微服务重构常见问题 1.领域驱动模型的困扰 比如听到很多理论比如领域驱动,那么到底需要不需要学习或者使用领域驱动呢? 2.系统的复杂性 重构的时候发现系统之间调用非常…

【Python】百度翻译的爬虫实现(后篇)

这个程序可以实现中英文的自动识别然后进行翻译 看着程序就很好理解。 import requestsimport jsonclass Translation():翻译def __init__(self,content):self.content contentself.url "http://fanyi.baidu.com/basetrans"self.headers {"User-Agent"…

美团即时物流的分布式系统架构设计

背景 美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验。最主要的收获包括两点: 即时物流业务对故障和高延迟的容忍度极低,在业务复…

Intellij IDEA单元测试提示Test events were not received

Intellij IDEA单元测试时提示Test events were not received 也就是可以运行test方法,也提示成功,但是看不到具体的执行结果。 Intellij IDEA从2019.2.1版本开始,会将Gradle管理的项目的测试代码,默认使用Gradle来运行&#xff0…

Linux下task_struct详解

背景:为了管理进程,操作系统必须对每个进程所做的事情进行清楚地描述,为此,操作系统使用数据结构来代表处理不同的实体,这个数据结构就是通常所说的进程描述符或进程控制块。在linux系统中,这就是task_stru…

【Python】数据提取xpath和lxml模块(豆瓣电影排行榜的爬虫)

xpath xpath:一门从html中提取数据的语言 xpath语法 1、选择节点(标签) /html/head/meta :能够选中html下的head下的所有的meta标签 2、// :能够从任意节点开始选择 //li:当前页面上所有的li标签 //html/head/link &a…

qt5.6.3下使用firebird

有人把firebird比作数据库界的瑞士军刀,想学习一下其在QT5.6中的使用,于是便开始了一场自己挖坑,自己埋的旅程。 环境说明:win7 64位QT5.6 mingw4.9 32位(好像官网上也没有64位,当然mingw也是32位的&#x…

【Python】数据提取xpath和lxml模块(糗事百科的爬虫)

程序中用到的一些零碎知识点: 一、列表推导式:帮助我们快速生成一堆数据的列表 1、format:字符串格式化的一种方式 >>> ["10月{}日".format(i) for i in range(1,10)] [10月1日, 10月2日, 10月3日, 10月4日, 10月5日, 1…

Linux Performance

性能专家Brendan Gregg的网站。 Linux性能 该页面链接到我创建的各种Linux性能材料,包括右侧的工具图。它们使用大字体来适合滑盖。您也可以将它们打印出来用于办公室墙壁。它们显示:Linux可观察性工具, Linux静态性能分析工具,…

07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器

LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/dunitian/LoTCodeBase/tree/master/LoTUI 先看在LoT.UI里面的应用效果图: 完整Demo:(https://gith…

workerman结合laravel开发在线聊天应用的示例代码

项目背景: 最近由于公司的业务需求,需要用到聊天功能。而且有比较多的个性化需求需要定制。之前使用别人的聊天组件是基于微擎的。如果要移植到普通的H5在逻辑修改还有定制上存在比较多的困难。为此只能克服困难,自己搭建一个吧 什么是Worker…

复杂系统设计 企业开发的困境

复杂系统设计源自我多年对企业复杂系统的设计的一些思考,类似日记吧,不断完善。 为什么从一个大公司的引入架构师甚至架构师组还是很难架构企业开发中的很多问题? 这些问题表现出架构上的复杂性,和业务上的复杂性。 有时候架构…

数据库服务器跟网站服务器间传输慢的问题

数据库服务器和网站服务器是分开的,现在从网站服务器这边查数据比较慢,什么原因??? 一、首先确定服务器之间的网络有没有问题 可以简单的在网站服务器上ping数据库服务器(反过来也可以)&#xf…

【Python】百度贴吧图片的爬虫实现(努力努力再努力)

学会爬取图片以后,第一时间去了张艺兴吧,哈哈哈哈哈哈 一定要放上一张爬取的照片,哼唧 import reimport requestsimport urllibclass Baidutieba():def __init__(self):self.url "http://tieba.baidu.com/p/4876047826?pn{}"#u…

cin、cout的重载

一、cin重载 1.cin为ostream类的成员 2.cin重载应为全局函数&#xff08;毕竟ostream是别人写好的&#xff09; 3.代码 a.核心代码 ostream & operator<<(ostream &os,const A &a)//const A &a是为了避免复制函数的调用 &#xff1b;ostream &o 相当…

第二次冲刺第十天

第二次冲刺今天就结束了&#xff0c;这十天来学会了不少的东西。 简单说一下昨天做的&#xff1a;整合各个部件的功能。 今天&#xff1a;小组进行总结&#xff0c;加强性能。 这十天来遇到的问题&#xff1a; 一&#xff0c;对于网络云端&#xff0c;之前都是其他小组成员在使…

说透泛型类和泛型方法以及Class<T>和Class<?>的差异

泛型类和泛型方法看起来似乎可以实现类似的功能&#xff0c;但是很多人并未真正掌握泛型方法&#xff0c;网上很多文章说了很多还是似是而非&#xff0c;特别是初学者还是搞不明白。 一.关于泛型方法 1.泛型方法可以独立于泛型类 2.泛型方法等效于泛型类里泛型参数方法&…

win10 +python 3.6.4安装scrapy

第一步&#xff1a; 首先&#xff0c;我们先在电脑上安装好python3.6并且配置好环境变量&#xff0c;以可以直接在命令行界面输入python命令可以出现如图的界面为主。 第二步&#xff1a; 升级pip &#xff0c;在cmd窗口中会有提示&#xff0c;没有提示的话就已经是最新版本了…

7 种 Javascript 常用设计模式学习笔记

7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制&#xff0c;并不是 23 种设计模式都常用。 有的是没有使用场景&#xff0c;有的模式使用场景非常少&#xff0c;所以只是列举 7 个常见的模式 本文的脉络&#xff1a; 设计与模式5 大设计原则 7 种常见的设计…

从难免的线上bug说起代码的思考

经常是某司线上又出bug了&#xff0c;然后是给公司造成多少损失&#xff0c;追根究底总是可以找到一些原因&#xff0c;诸如&#xff1a;写代码逻辑考虑不全面&#xff0c;或者代码有硬伤&#xff0c;也有测试不充分&#xff0c;甚至不测试都有&#xff0c;也有是运维的问题等等…

PHP-Fpm应用池配置

//php.net php-fpm配置简介http://php.net/manual/zh/install.fpm.configuration.php//Global Options//pool defined[www]user nobodygroup nobodylisten 127.0.0.1:9000pm dynamicpm.max_children 5pm.start_servers 2pm.min_spare_servers 1pm.max_spare_servers 3s…

【Python】百度首页GIF动画的爬虫

今天百度首页的GIF动画很可爱&#xff0c;就想着用才学的爬虫爬取一下&#xff0c;虽然直接点击“图片另存为”就可以了 import requestsimport urllibclass Gif():def __init__(self):self.url "https://www.baidu.com/"self.headers {"User-Agent": …

CSS题目系列(3)- 实现文字切割效果

描述 有一天逛 Codepen 的时候&#xff0c;看到这么一个效果&#xff1a;将文字上下切开两半。 点进去看了一下代码&#xff0c;发现原理很简单&#xff0c;大概就是通过伪类使用attr()函数获取内容&#xff0c;然后进行定位。 你可以点下方链接查看效果&#xff1a; gd4ark.gi…

Java开发字符串JSON处理

需求很简单就是数据库存json。 数据库字段 varchar 入参request 定义 List<String> 如果不定义这个 而是定义String那么需要加"/转义比较难看 这样就只要入参传这个就行了&#xff1a; "xxxIds": ["33","44"], 数据库也是…

1.JSONObject与JSONArray的使用

参考文献&#xff1a; http://blog.csdn.net/huangwuyi/article/details/5412500 1.JAR包简介 要使程序可以运行必须引入JSON-lib包&#xff0c;JSON-lib包同时依赖于以下的JAR包&#xff1a; commons-lang.jarcommons-beanutils.jarcommons-collections.jarcommons-logging.ja…

【Python】Scrapy爬虫实战(豆瓣电影 Top 250)

今天一天都在弄Scrapy&#xff0c;虽然爬虫起来真的很快&#xff0c;很有效率&#xff0c;但是......捣鼓了一天 豆瓣电影 Top 250&#xff1a;https://movie.douban.com/top250 安装好的scrapy 在你想要的文件夹的目录下输入命令&#xff1a; scrapy startproject douban_m…

vmrun 批量创建vmware虚拟机

1 准备模板机 具体步骤如下&#xff1a; 1. 下载镜像安装系统 https://mirrors.aliyun.com/centos/7.5.1804/isos/x86_64/2. 安装完成配置好IP &#xff0c;关闭SELINUX ,关闭firewalld ,修改网卡名 3. 预设置好修改其他机器IP脚本 1.1 安装系统 略 1.2 模板机的设置 修改网卡名…

暗时间:开发效率为何如此低下

产品 开发 测试 三者都理解不一致。 产品怎么样表达出自己的诉求&#xff0c;是否写清文档就够了。 开发觉得自己沟通了&#xff0c;但是为什么测试一提测又许多问题。 测试的case看似都一起评审了。 而这样的结果必然是重新修修补补&#xff0c;怎么样事前把问题全部解…

【Python】Scrapy爬虫实战(传智播客老师简介)

在文件夹里创建一个爬虫项目 scrapy startproject ITcast 在spiders目录下&#xff1a; scrapy genspider itcast ------------------------------------------------------------------------------------------------------------------------------------------------------…