原文出处:http://cmsblogs.com/?p=2652作者:chenssy

在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为【死磕 Spring】系列博客的第一篇博文,主要介绍 IoC 基本概念和各个组件。

IOC 理论 IoC 全称为

Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入。 如何理解“控制反转”好呢?理解好它的关键在于我们需要回答如下四个问题: 1. 谁控制谁 2. 控制什么 3. 为何是反转 4. 哪些方面反转了 在回答这四个问题之前,我们先看 IOC 的定义:

所谓 IOC ,就是由 Spring IOC 容器来负责对象的生命周期和对象之间的关系 上面这句话是整个 IoC 理论的核心。如何来理解这句话?我们引用一个例子来走阐述(看完该例子上面四个问题也就不是问题了)。 已找女朋友为例(对于程序猿来说这个值得探究的问题)。一般情况下我们是如何来找女朋友的呢?首先我们需要根据自己的需求(漂亮、身材好、性格好)找一个妹子,然后到处打听她的兴趣爱好、微信、电话号码,然后各种投其所好送其所要,最后追到手。如下:

这就是我们通常做事的方式,如果我们需要某个对象,一般都是采用这种直接创建的方式(

new BeautifulGirl()),这个过程复杂而又繁琐,而且我们必须要面对每个环节,同时使用完成之后我们还要负责销毁它,在这种情况下我们的对象与它所依赖的对象耦合在一起。 其实我们需要思考一个问题?我们每次用到自己依赖的对象真的需要自己去创建吗?我们知道,我们依赖对象其实并不是依赖该对象本身,而是依赖它所提供的服务,只要在我们需要它的时候,它能够及时提供服务即可,至于它是我们主动去创建的还是别人送给我们的,其实并不是那么重要。再说了,相比于自己千辛万苦去创建它还要管理、善后而言,直接有人送过来是不是显得更加好呢? 这个给我们送东西的“人” 就是 IoC,在上面的例子中,它就相当于一个婚介公司,作为一个婚介公司它管理着很多男男女女的资料,当我们需要一个女朋友的时候,直接跟婚介公司提出我们的需求,婚介公司则会根据我们的需求提供一个妹子给我们,我们只需要负责谈恋爱,生猴子就行了。你看,这样是不是很简单明了。 诚然,作为婚介公司的 IoC 帮我们省略了找女朋友的繁杂过程,将原来的主动寻找变成了现在的被动接受(符合我们的要求),更加简洁轻便。你想啊,原来你还得鞍马前后,各种巴结,什么东西都需要自己去亲力亲为,现在好了,直接有人把现成的送过来,多么美妙的事情啊。所以,简单点说,IoC 的理念就是让别人为你服务,如下图(摘自Spring揭秘):

在没有引入 IoC 的时候,被注入的对象直接依赖于被依赖的对象,有了 IoC 后,两者及其他们的关系都是通过 Ioc Service Provider 来统一管理维护的。被注入的对象需要什么,直接跟 IoC Service Provider 打声招呼,后者就会把相应的被依赖对象注入到被注入的对象中,从而达到 IOC Service Provider 为被注入对象服务的目的。所以 IoC 就是这么简单!原来是需要什么东西自己去拿,现在是需要什么东西让别人(IOC Service Provider)送过来 现在在看上面那四个问题,答案就显得非常明显了: 1. 谁控制谁:在传统的开发模式下,我们都是采用直接 new 一个对象的方式来创建对象,也就是说你依赖的对象直接由你自己控制,但是有了 IOC 容器后,则直接由 IoC 容器来控制。所以“谁控制谁”,当然是 IoC 容器控制对象。 2. 控制什么:控制对象。 3. 为何是反转:没有 IoC 的时候我们都是在自己对象中主动去创建被依赖的对象,这是正转。但是有了 IoC 后,所依赖的对象直接由 IoC 容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是反转。 4. 哪些方面反转了:所依赖对象的获取被反转了。 妹子有了,但是如何拥有妹子呢?这也是一门学问。

  1. 可能你比较牛逼,刚刚出生的时候就指腹为婚了。
  2. 大多数情况我们还是会考虑自己想要什么样的妹子,所以还是需要向婚介公司打招呼的。
  3. 还有一种情况就是,你根本就不知道自己想要什么样的妹子,直接跟婚介公司说,我就要一个这样的妹子。 所以,IOC Service Provider 为被注入对象提供被依赖对象也有如下几种方式:构造方法注入、stter方法注入、接口注入。

构造器注入 构造器注入,顾名思义就是被注入的对象通过在其构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。

YoungMan(BeautifulGirl beautifulGirl){ this.beautifulGirl = beautifulGirl;}

构造器注入方式比较直观,对象构造完毕后就可以直接使用,这就好比你出生你家里就给你指定了你媳妇。

setter 方法注入 对于 JavaBean 对象而言,我们一般都是通过 getter 和 setter 方法来访问和设置对象的属性。所以,当前对象只需要为其所依赖的对象提供相对应的 setter 方法,就可以通过该方法将相应的依赖对象设置到被注入对象中。如下:

public class YoungMan { private BeautifulGirl beautifulGirl; public void setBeautifulGirl(BeautifulGirl beautifulGirl) { this.beautifulGirl = beautifulGirl; }}

相比于构造器注入,setter 方式注入会显得比较宽松灵活些,它可以在任何时候进行注入(当然是在使用依赖对象之前),这就好比你可以先把自己想要的妹子想好了,然后再跟婚介公司打招呼,你可以要林志玲款式的,赵丽颖款式的,甚至凤姐哪款的,随意性较强。

接口方式注入 接口方式注入显得比较霸道,因为它需要被依赖的对象实现不必要的接口,带有侵入性。一般都不推荐这种方式。 * * *关于 IOC 理论部分,笔者不在阐述,这里推荐几篇博客阅读:

  • 谈谈对Spring IOC的理解:http://www.cnblogs.com/xdp-gacl/p/4249939.html
  • Spring的IOC原理[通俗解释一下]:https://blog.csdn.net/m13666368773/article/details/7802126
  • spring ioc原理(看完后大家可以自己写一个spring):https://blog.csdn.net/it_man/article/details/4402245

各个组件

先看下图(摘自:http://singleant.iteye.com/blog/1177358)

该图为 ClassPathXmlApplicationContext 的类继承体系结构,虽然只有一部分,但是它基本上包含了 IOC 体系中大部分的核心类和接口。 下面我们就针对这个图进行简单的拆分和补充说明。 Resource体系 Resource,对资源的抽象,它的每一个实现类都代表了一种资源的访问策略,如ClasspathResource 、 URLResource ,FileSystemResource 等。

有了资源,就应该有资源加载,Spring 利用 ResourceLoader 来进行统一资源加载,类图如下:

BeanFactory 体系 BeanFactory 是一个非常纯粹的 bean 容器,它是 IOC 必备的数据结构,其中 BeanDefinition 是她的基本结构,它内部维护着一个 BeanDefinition map ,并可根据 BeanDefinition 的描述进行 bean 的创建和管理。

BeanFacoty 有三个直接子类 ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory,DefaultListableBeanFactory 为最终默认实现,它实现了所有接口。 Beandefinition 体系 BeanDefinition 用来描述 Spring 中的 Bean 对象。

BeandefinitionReader体系 BeanDefinitionReader 的作用是读取 Spring 的配置文件的内容,并将其转换成 Ioc 容器内部的数据结构:BeanDefinition。

ApplicationContext体系 这个就是大名鼎鼎的 Spring 容器,它叫做应用上下文,与我们应用息息相关,她继承 BeanFactory,所以它是 BeanFactory 的扩展升级版,如果BeanFactory 是屌丝的话,那么 ApplicationContext 则是名副其实的高富帅。由于 ApplicationContext 的结构就决定了它与 BeanFactory 的不同,其主要区别有: 1. 继承 MessageSource,提供国际化的标准访问策略。 2. 继承 ApplicationEventPublisher ,提供强大的事件机制。 3. 扩展 ResourceLoader,可以用来加载多个 Resource,可以灵活访问不同的资源。 4. 对 Web 应用的支持。 下图来源:https://blog.csdn.net/yujin753/article/details/47043143

上面五个体系可以说是 Spring IoC 中最核心的部分,后面博文也是针对这五个部分进行源码分析。其实 IoC 咋一看还是挺简单的,无非就是将配置文件(暂且认为是 xml 文件)进行解析(分析 xml 谁不会啊),然后放到一个 Map 里面就差不多了,初看有道理,其实要面临的问题还是有很多的,下面就劳烦各位看客跟着 LZ 博客来一步一步揭开 Spring IoC 的神秘面纱。

此系列博文为 LZ 学习、研究 Spring 机制和源码的学习笔记,会涉及参考别人的博文和书籍内容,如有雷同,纯属借鉴,当然 LZ 会标明参考来源。同时由于知识面和能力的问题,文章中难免会出现错误之处,如有,望各位大佬指出,不胜感激LZ 写此系列博客时,Spring 最新版本为 5.0.6.RELEASE ,所以此系列博客所有源码来源均为 5.0.6.RELEASE

spring揭秘_「死磕 Spring」—– IOC 之深入理解 Spring IoC相关推荐

  1. preg_match 参数获取两个_「死磕 Spring」—– IOC 之 获取 Document 对象

    原文出自:http://cmsblogs.com作者:chenssy 在 XmlBeanDefinitionReader.doLoadDocument() 方法中做了两件事情,一是调用 getVali ...

  2. 「死磕Java并发编程」说说Java Atomic 原子类的实现原理

    <死磕 Java 并发编程>系列连载中,大家可以关注一波. 「死磕 Java 并发编程」阿里二面,面试官:说说 Java CAS 原理? 「死磕 Java 并发编程」面试官:说说什么是 J ...

  3. spring揭秘_被问到了! Spring 和 Spring Boot 之间到底有啥区别?

    相信很多小伙伴和我一样,常用Spring 和Spring Boot 但是就是没有研究二者之间到底有什么区别? 今天就来大揭秘 ↓ 概述 对于 Spring和 SpringBoot到底有什么区别,我听到 ...

  4. 多模态语义分析_「CV学霸开讲」卷积神经网络压缩、多模态的语义分析研究

    原标题:「CV学霸开讲」卷积神经网络压缩.多模态的语义分析研究 [新智元导读]2017年度百度奖学金10位候选人中,人大的陈师哲和北大的王云鹤所学专业主要集中在计算机视觉,本文将详细呈现CV学子的求学 ...

  5. 背景宽高随文本变化_「只要功夫深 不用关键帧」之文本图层小技巧

    「只要功夫深 不用关键帧」将不定期更新一些AE表达式和脚本的奇技淫巧,希望能给大家带来一些启发. 上周有朋友遇到这么个问题: 对一段文字,不管文字长度如何变化,想让背景到文字的边距始终保持不变,在 A ...

  6. 不等待输入_「对方正在输入……」的提示,给聊天带来什么影响?

    看着微信对话界面的「对方正在输入-」,你是否急于知道对方的输入内容?大部分时候,虽然只有十几秒,但是却感觉过了数分钟.这个功能,究竟有没有起到即时反馈的作用呢? 从时间知觉的角度看,「对方正在输入-」 ...

  7. java加载c库阻塞_【死磕Java並發】-----J.U.C之阻塞隊列:DelayQueue

    DelayQueue是一個支持延時獲取元素的無界阻塞隊列.里面的元素全部都是"可延期"的元素,列頭的元素是最先"到期"的元素,如果隊列里面沒有元素到期,是不能從 ...

  8. python列表框_「每日一练」Python列表框部件的运用

    原标题:「每日一练」Python列表框部件的运用 用Python就一定要用到界面操作,有一个好的用户界面,才会有好的用户体验,下边就开始创建我们的主窗口,并设置相应的列表框部件吧! 案例 创建主窗口, ...

  9. ccd相机好修吗_「CCD购买指南 」CCD废片大公开

    最近小红书上CCD大热,当我看到花几十块钱就能拥有一部相机的时候,贫民窟的我,激动的心,颤抖的手. 相信在看这篇笔记的你们也是这种心情. 千万别啊‼️‼️ 这样冲动容易被坑 花三分钟看完我的笔记,你会 ...

  10. python断点调试_「Python调试器」,快速定位各种疑难杂症!!!

    在很多的编辑器其实都带着「调试程序」的功能,比如写 c/c++ 的 codeblocks,写 Python 的 pycharm,这种图形界面的使用和显示都相当友好,简单方便易学,这个不是我这篇文章要讲 ...

最新文章

  1. 服务器与浏览器数据传输过程中编码问题
  2. 视频内容理解在Hulu的应用与实践
  3. HDU - 4253 Two Famous Companies(二分+最小生成树)
  4. 【php】正则无法截取\反斜杠的解决方法
  5. hdu 1698 Just a Hook
  6. DynamipsGUI的使用+vmware通讯建立
  7. 如何测试硬盘软件,win10系统怎么用硬盘检测工具HDTune【图文】
  8. 获取UI控件位置信息
  9. html代码在线运行_在线运行html代码
  10. ES的基本API操作
  11. 用Look'n'Stop防火墙实现ARP终极防御
  12. 中国股市最“暴利”时代,而有的人活在15年的熊市!
  13. python中装饰器修复技术_12步轻松搞定Python装饰器
  14. 建筑CAD《超级绘图王》简介
  15. 如何与陌生人搭讪十技巧
  16. 推荐系统6——基于标签的推荐方法
  17. 机器人/无人驾驶参考资源
  18. rust游戏解封了吗_又一款分手游戏!只只大冒险操作简单但需要默契
  19. 对FckEditor编辑器在MAXTHON浏览器下选择服务器文件对话框显示不正常的改进
  20. 横河电机与Power Factors宣布可再生能源资产性能管理平台的经销协议

热门文章

  1. html5+JS调用摄像头示例
  2. UE4C++ Http下载文件
  3. 数字信号处理----数字上变频和下变频都FPGA实现
  4. 几何画板如何生成三角函数图像
  5. 那是飞扬的青春—小评《DOOM启示录》
  6. python open读取_读取文件—open()、read()
  7. 嵌入式C高质量编程培训心得笔记
  8. 单片机c语言编程实训报告,单片机实训报告范文
  9. 网易云音乐歌词下载器
  10. 网易云爬取歌词进行歌词词云可视化