spring 的自我理解【IOC、DI】

本贴最后更新于 2687 天前,其中的信息可能已经时移世异

说起 spring 框架,我认为严格意义上来说 spring 更像是一个粘合剂【纯属个人观点】。一般都叫 spring 容器。因为它粘合了别的框架或者组件。所以 spring 是个容器。程序开发的模块组件都可以通过 spring 这个容器进行组装拼合,spring 为我们提供了很多管理功能。而且,它是一个轻量级的容器。【当 spring 启动时,创建和销毁的资源都非常少】它的侵入性非常小,也可以说是耦合性很低。可以很轻易的替换掉它,而不需要做太大的改动,它对别的组件的依赖非常小。

fe5cf4ed04074245afb47fdaab9b00f0-image.png

谈到 spring 必然要想到 IOC(Inversion of Control)【控制反转】,它不是一门技术,而是一种设计思想。在 java 开发中,IOC 意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。先要明确谁控制谁,控制什么。
在传统的 java SE 设计中我们直接在对象内部通过 new 进行对象的创建,是程序主动去创建依赖对象;而 IOC 是有一个专门的容器来创建这些对象,即有 IOC 容器来控制对象的创建;

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

举一个通俗易懂的例子:比如芈月传这个电视剧的剧本,如果编剧在写剧本的时候把芈月直接写为孙俪,直接围绕孙俪这个对象去编剧本,这种方式就相当于传统的 java SE 的设计思想。而当有了 IOC 思想之后,编剧写剧本的时候直接写芈月说了什么话,做了什么事直接围绕戏剧人物进行刻画描述,而找演员(创建对象)这种事情交给导演去做。而不是剧本直接定死的,即使孙俪档期冲突了,也可以找王丽,李丽之类的。这就是我对控制反转的个人见解。

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

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

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

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

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

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

  IoC 和 DI 由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以 2004 年大师级人物 Martin Fowler 又给出了一个新的名字:“依赖注入”,相对 IoC 而言,“依赖注入”明确描述了“被注入对象依赖 IoC 容器配置依赖对象”。

再举一个简单的例子
所谓依赖,从程序的角度看,就是比如 A 要调用 B 的方法,那么 A 就依赖于 B,反正 A 要用到 B,则 A 依赖于 B。
所谓倒置,你必须理解如果不倒置,会怎么着,因为 A 必须要有 B,才可以调用 B,如果不倒置,意思就是 A 主动获取 B 的实例:B b = new B(),这就是最简单的获取 B 实例的方法(当然还有各种设计模式可以帮助你去获得 B 的实例,比如工厂、Locator 等等),然后你就可以调用 b 对象了。
所以,不倒置,意味着 A 要主动获取 B,才能使用 B;到了这里,你就应该明白了倒置的意思了。倒置就是 A 要调用 B 的话,A 并不需要主动获取 B,而是由其它人自动将 B 送上门来。

形象的举例就是:

通常情况下,假如你有一天在家里饿了,要吃饭,那么你可以到你小区外面的饭店去,告诉他们,你需要一份黄焖鸡米饭,然后小卖部给你做一份黄焖鸡米饭!

这本来没有太大问题,关键是如果饭店很远,那么你必须知道:从你家如何到饭店;饭店里的黄焖鸡米饭是否已经售罄;你还要考虑是否开着车去;等等等等,也许有太多的问题要考虑了。也就是说,为了吃上一顿黄焖鸡米饭,你还可能需要依赖于车等等这些交通工具或别的工具,问题是不是变得复杂了?那么如何解决这个问题呢?

解决这个问题的方法很简单:饿了么应运而生,凡是饿了么的会员,你只要告知饿了么 app 你需要什么,骑手将主动把货物给你送上门来!这样一来,你只需要做两件事情,你就可以活得更加轻松自在:
第一:向饿了么注册为会员
第二:在饿了么上面下单

是不是和 Spring 的做法很类似呢?Spring 就是饿了么、饭店,你就是 A 对象,黄焖鸡米饭就是 B 对象
第一:在 Spring 中声明一个类:A
第二:告诉 Spring,A 需要 B

假设 A 是 UserAction 类,而 B 是 UserService 类

     

在 Spring 这个饿了么 app(工厂)中,有很多对象/服务:userService,documentService,orgService,也有很多会员:userAction 等等,声明 userAction 需要 userService 即可,Spring 将通过你给它提供的通道主动把 userService 送上门来,因此 UserAction 的代码示例类似如下所示:

package org.leadfar.web; public class UserAction{      private UserService userService;      public String login(){           userService.valifyUser(xxx);      }      public void setUserService(UserService userService){            this.userService = userService;      } }

在这段代码里面,你无需自己创建 UserService 对象(Spring 作为背后无形的手,把 UserService 对象通过你定义的 setUserService()方法把它主动送给了你,这就叫依赖注入!)

所以个人总结下来就是
ioc 相当于 平时我们使用的工厂。
di 相当于 平时我们的 setter 方法。

  • 框架
    46 引用 • 346 回帖 • 1 关注
  • IoC
    18 引用 • 29 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 489 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 14 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 2 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    30 引用 • 108 回帖
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 259 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 656 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 2 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • OneDrive
    2 引用 • 1 关注
  • Excel
    31 引用 • 28 回帖
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 253 关注
  • 996
    13 引用 • 200 回帖 • 10 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 76 回帖 • 2 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    581 引用 • 3535 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 154 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 71 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 1 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 3 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 635 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖
  • 安全

    安全永远都不是一个小问题。

    204 引用 • 816 回帖
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 3 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    85 引用 • 165 回帖 • 5 关注