Spring IoC 到底是什么
前言
「上一篇文章」我们对 Spring 有了初步的认识,而 Spring 全家桶中几乎所有组件都是依赖于 IoC 的。
刚开始听到 IoC,会觉得特别高大上,但其实掰开了很简单。
跟着我的脚步,一文带你吃透 IoC 原理。
本文主要讲原理,围绕“是何”、“为何”来谈,下一篇文章会讲实践部分,也就是“如何”。
文本已收录至我的 Github: https://github.com/xiaoqi6666/NYCSDE

是何
上一篇文章有同学问我在官网该看哪些内容,怎么找的,那今天的截图里都会有链接。
初识 IoC
根据上一篇文章我们说的,Spring 全家桶中最重要的几个项目都是基于 Spring Framework 的,所以我们就以 Spring Framework 为例来看文档。
首先它的右侧有 Github 的链接,另外点到「LEARN」这里,就会看到各个版本的文档。

那我们点「Reference Doc」,就能够看到它的一些模块的介绍:
(等下... 模块?什么是模块?这个问题下文回答。)

第一章 Overview,讲述它的历史、设计原理等等;
第二章 Core,包含了 IoC 容器,AOP 等等,那自然是讲 Spring 的核心了,要点进去好好看了。

点进去之后发现了宝贵的学习资料,一切的 what, why, how 都可以在这里找到答案。

这里很好的解释了大名鼎鼎的 IoC - Inversion of Control, 控制反转。
每次读都会有新的体会和收获。
我粗略的总结一下:控制反转就是把创建和管理 bean 的过程转移给了第三方。而这个第三方,就是 Spring IoC Container,对于 IoC 来说,最重要的就是容器。
容器负责创建、配置和管理 bean,也就是它管理着 bean 的生命,控制着 bean 的依赖注入。
通俗点讲,因为项目中每次创建对象是很麻烦的,所以我们使用 Spring IoC 容器来管理这些对象,需要的时候你就直接用,不用管它是怎么来的、什么时候要销毁,只管用就好了。
举个例子,就好像父母没时间管孩子,就把小朋友交给托管所,就安心的去上班而不用管孩子了。
托儿所,就是第三方容器,负责管理小朋友的吃喝玩乐;
父母,相当于程序员,只管接送孩子,不用管他们吃喝。
等下,bean 又是什么?
Bean 其实就是包装了的 Object,无论是控制反转还是依赖注入,它们的主语都是 object,而 bean 就是由第三方包装好了的 object。(想一下别人送礼物给你的时候都是要包装一下的,自己造的就免了。
IoC 容器
既然说容器是 IoC 最重要的部分,那么 Spring 如何设计容器的呢?
还是回到官网,第二段有介绍哦:

答:使用 ApplicationContext,它是 BeanFactory 的子类,更好的补充并实现了 BeanFactory 的。
BeanFactory 简单粗暴,可以理解为 HashMap:
- Key - bean name
- Value - bean object
但它一般只有 get, put 两个功能,所以称之为“低级容器”。
而 ApplicationContext 多了很多功能,因为它继承了多个接口,可称之为“高级容器”。在下文的搭建项目中,我们会使用它。

ApplicationContext 的里面有两个具体的实现子类,用来读取配置配件的:
ClassPathXmlApplicationContext- 从 class path 中加载配置文件,更常用一些;FileSystemXmlApplicationContext- 从本地文件中加载配置文件,不是很常用,如果再到 Linux 环境中,还要改路径,不是很方便。
当我们点开 ClassPathXmlApplicationContext 时,发现它并不是直接继承 ApplicationContext 的,它有很多层的依赖关系,每层的子类都是对父类的补充实现。
而再往上找,发现最上层的 class 回到了 BeanFactory,所以它非常重要。
要注意,Spring 中还有个 FactoryBean,两者并没有特别的关系,只是名字比较接近,所以不要弄混了顺序。
为了好理解 IoC,我们先来回顾一下不用 IoC 时写代码的过程。
深入理解 IoC
这里用经典 class Rectangle 来举例:
- 两个变量:长和宽
- 自动生成
set()方法和toString()方法
注意 ️:一定要生成 set() 方法,因为 Spring IoC 就是通过这个 set() 方法注入的;
toString() 方法是为了我们方便打印查看。
public class Rectangle {
private int width;
private int length;
public Rectangle() {
System.out.println("Hello World!");
}
public void setWidth(int widTth) {
this.width = widTth;
}
public void setLength(int length) {
this.length = length;
}
@Override
public String toString() {
return "Rectangle{" +
"width=" + width +
", length=" + length +
'}';
}
}
然后在 test 文件中手动用 set() 方法给变量赋值。
嗯,其实这个就是「解藕」的过程!
public class MyTest {
@Test
public void myTest() {
Rectangle rect = new Rectangle();
rect.setLength(2);
rect.setWidth(3);
System.out.println(rect);
}
}
其实这就是 IoC 给属性赋值的实现方法,我们把「创建对象的过程」转移给了 set() 方法,而不是靠自己去 new,就不是自己创建的了。
这里我所说的“自己创建”,指的是直接在对象内部来 new,是程序主动创建对象的正向的过程;
这里使用 set() 方法,是别人(test)给我的;
而 IoC 是用它的容器来创建、管理这些对象的,其实也是用的这个 set() 方法,不信,你把这个这个方法去掉或者改个名字试试?
几个关键问题:
何为控制,控制的是什么?
答:是 bean 的创建、管理的权利,控制 bean 的整个生命周期。
何为反转,反转了什么?
答:把这个权利交给了 Spring 容器,而不是自己去控制,就是反转。
由之前的自己主动创建对象,变成现在被动接收别人给我们的对象的过程,这就是反转。
举个生活中的例子,主动投资和被动投资。
自己炒股、选股票的人就是主动投资,主动权掌握在自己的手中;
而买基金的人就是被动投资,把主动权交给了基金经理,除非你把这个基金卖了,否则具体选哪些投资产品都是基金经理决定的。
依赖注入
回到文档中,第二句话它说:IoC is also known as DI.
我们来谈谈 dependency injection - 依赖注入。
何为依赖,依赖什么?
程序运行需要依赖外部的资源,提供程序内对象的所需要的数据、资源。
何为注入,注入什么?
配置文件把资源从外部注入到内部,容器加载了外部的文件、对象、数据,然后把这些资源注入给程序内的对象,维护了程序内外对象之间的依赖关系。
所以说,控制反转是通过依赖注入实现的。
但是你品,你细品,它们是有差别的,像是「从不同角度描述的同一件事」:
- IoC 是设计思想,DI 是具体的实现方式;
- IoC 是理论,DI 是实践;
从而实现对象之间的解藕。
当然,IoC 也可以通过其他的方式来实现,而 DI 只是 Spring 的选择。
IoC 和 DI 也并非 Spring 框架提出来的,Spring 只是应用了这个设计思想和理念到自己的框架里去。
为何
那么为什么要用 IoC 这种思想呢?换句话说,IoC 能给我们带来什么好处?
答:解藕。
它把对象之间的依赖关系转成用配置文件来管理,由 Spring IoC Container 来管理。
在项目中,底层的实现都是由很多个对象组成的,对象之间彼此合作实现项目的业务逻辑。但是,很多很多对象紧密结合在一起,一旦有一方出问题了,必然会对其他对象有所影响,所以才有了解藕的这种设计思想。


如上图所示,本来 ABCD 是互相关联在一起的,当加入第三方容器的管理之后,每个对象都和第三方法的 IoC 容器关联,彼此之间不再直接联系在一起了,没有了耦合关系,全部对象都交由容器来控制,降低了这些对象的亲密度,就叫“解藕”。
那么我们下一篇文章就来讲一下如何搭建一个 Spring 项目。
如果你喜欢这篇文章,记得给我点赞留言哦~你们的支持和认可,就是我创作的最大动力,我们下篇文章见!
我是小齐,纽约程序媛,终生学习者,每天晚上 9 点,云自习室里不见不散!
更多干货文章见我的 Github: https://github.com/xiaoqi6666/NYCSDE
Spring IoC 到底是什么的更多相关文章
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- Spring系列之谈谈对Spring IOC的理解
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- [Spring框架]Spring IOC的原理及详解。
这里感谢 CSDN 的原博客:http://blog.csdn.net/m13666368773/article/details/7802126 看后 受益匪浅,这里再重温一遍Spring IOC ...
- 走进 Spring IOC 的世界
转载出自:http://blog.csdn.net/m13666368773/article/details/7802126 1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的 ...
- 解读Spring Ioc容器设计图
在Spring Ioc容器的设计中,有俩个主要的容器系列:一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器最基本的功能:另外一个是ApplicationContext应用上下 ...
- Spring IOC容器基本原理
2.2.1 IOC容器的概念IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IOC容器 ...
- 深入理解Spring IOC工作原理
为什么会出现spring,spring出现解决了什么问题? 1.分析普通多层架构存在的问题 JSP->Servlet->Service->Dao 层与层之间的依赖很强,属于耦合而且是 ...
- 1.3浅谈Spring(IOC容器的实现)
这一节我们来讨论IOC容器到底做了什么. 还是借用之前的那段代码 ClassPathXmlApplicationContext app = new ClassPathXmlApplicationCon ...
- Spring Ioc 常用注解
在开发中spring ioc的配置方式有多种方式,常用的一般都是byName.byType .以及其自动装配可以查看http://www.cnblogs.com/gubai/p/9140840.htm ...
随机推荐
- Java入门到实践系列(2)——Java环境搭建
一.上集回顾 在<Java入门到实践系列(1)--Java简介>中提到过,Java程序是运行在Java虚拟机的,也展示过下面这张图. JDK:Java程序开发工具包. JRE:Java运行 ...
- 博客主题推荐——复杂&简单
首先感谢原作者cjunn提供的主题autm,以下配置都基于此主题设定.很多小伙伴喜欢现在的样式,分享如下.只需简单几步即可. 如果你想使用本博客主题样式,并希望能得到远程推送更新,只需查看 快速部署. ...
- 【算法•日更•第二期】查找算法:三分VS二分
▎前言:函数 如果你已经上过初二的数学课了,那么你十有八九会被函数折磨到吐血,这是一种中考压轴题类的题目,往往分类讨论到你恶心.不过没学过也不打紧,现场讲解一下: ☞『数学中的函数』 一般地,如果在一 ...
- 【Apollo】(1)--- Apollo入门介绍篇
Apollo入门介绍篇 Apollo有一点很好,就是它是由国内携程团队开发,而且文档写的很全,代码也完全开源.如果去了解它也可以直接去看它的官方文档. 一.配置中心概念 1.背景 在实际开发中都会与配 ...
- Spark QuantileDiscretizer 分位数离散器
1.概念 接收具有连续特征的列,并输出具有合并分类特征的列.按分位数,对给出的数据列进行离散化分箱处理. 和Bucketizer(分箱处理)一样也是:将连续数值特征转换为离散类别特征.实际上Class ...
- 用java编程在10000到99999中的数字中找到aabcc类型的数字
package com.diyo.offer; public class FindNum { public static void main(String[] args) { int count = ...
- dcoker 小应用(一)
docker 创建Ubuntu系统 1.创建Dockerfile #ubuntu:14.04 image FROM ubuntu:14.04 MAINTAINER XXX, xxx@xxx.com R ...
- 个人项目(C语言)
GitHub地址:https://github.com/dachai9/personal-project.git 1. WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数 ...
- DOM 事件机制&事件委托
一.事件机制 事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自MDN).每个事件都有事件处理器(有时也叫事件监听器),也就是触 ...
- Linux教学资源服务器构建
1. 需求分析 1.1 课题简介 随着计算机互联网的迅速发展,大多数学校已经实现教学的信息化,从传统的黑板教学方式转变为现阶段的多媒体教学,教学的资源,素材课件,甚至学生的作业也都实现数字化,为了实现 ...