Spring IoC (控制反转)

这篇具有很好参考价值的文章主要介绍了Spring IoC (控制反转)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则。
Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。

控制反转(IoC )

在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。为了方便理解和描述,我们可以将前者称为“调用者”,将后者称为“被调用者”。也就是说,调用者掌握着被调用者对象创建的控制权。

但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里的,其大致步骤如下。

  1. 开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 <bean> 标签、在 Java 类上使用 @Component 注解等。
  2. Spring 启动时,IOC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IOC 容器创建并管理的对象被称为 Spring Bean。
  3. 当我们想要使用某个 Bean 时,可以直接从 IOC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法),而不需要手动通过代码(例如 new Obejct() 的方式)创建。


IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IoC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IoC 容器创建它所需要的对象(Bean)。

这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IoC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。

依赖注入(DI)

在了解了 IoC 之后,我们还需要了解另外一个非常重要的概念:依赖注入。

依赖注入(Denpendency Injection,简写为 DI)是 Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩,无法让人很直接的理解“到底是哪里反转了”,因此他建议使用“依赖注入”来代替“控制反转”。

在面向对象中,对象和对象之间是存在一种叫做“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。

例如,有一个名为 B 的 Java 类,它的代码如下。 

public class B {
    String bid;
    A a;
}

从代码可以看出,B 中存在一个 A 类型的对象属性 a,此时我们就可以说 B 的对象依赖于对象 a。而依赖注入就是基于这种“依赖关系”而产生的。

控制反转核心思想就是由 Spring 负责对象的创建。在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。

IoC 的工作原理

在 Java 软件开发过程中,系统中的各个对象之间、各个模块之间、软件系统和硬件系统之间,或多或少都存在一定的耦合关系。

若一个系统的耦合度过高,那么就会造成难以维护的问题,但完全没有耦合的代码几乎无法完成任何工作,这是由于几乎所有的功能都需要代码之间相互协作、相互依赖才能完成。因此我们在程序设计时,所秉承的思想一般都是在不影响系统功能的前提下,最大限度的降低耦合度。

IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。

  1. 在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;
  2. 我们可以把 IOC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;
  3. 容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;
  4. IOC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean),并根据依赖关系将这个对象注入到依赖它的对象中。

由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的,并没有在代码中紧密耦合,因此即使对象发生改变,我们也只需要在配置文件中进行修改即可,而无须对 Java 代码进行修改,这就是 Spring IOC 实现解耦的原理。

IoC 容器的两种实现

IoC 思想基于 IoC 容器实现的,IoC 容器底层其实就是一个 Bean 工厂。Spring 框架为我们提供了两种不同类型 IoC 容器,它们分别是 BeanFactory 和 ApplicationContext。

BeanFactory

BeanFactory 是 IoC 容器的基本实现,也是 Spring 提供的最简单的 IoC 容器,它提供了 IoC 容器最基本的功能,由 org.springframework.beans.factory.BeanFactory 接口定义。

BeanFactory 采用懒加载(lazy-load)机制,容器在加载配置文件时并不会立刻创建 Java 对象,只有程序中获取(使用)这个对对象时才会创建。

示例 1

BeanFactory 的使用。

在 HelloSpring 项目中,将 MainApp 的代码修改为使用 BeanFactory 获取 HelloWorld 的对象,具体代码如下。 

public static void main(String[] args) {
    BeanFactory context = new ClassPathXmlApplicationContext("Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 2运行 MainApp.java,控制台输出如下。

message : Hello World!

BeanFactory 是 Spring 内部使用接口,通常情况下不提供给开发人员使用。  

ApplicationContext

ApplicationContext 是 BeanFactory 接口的子接口,是对 BeanFactory 的扩展。ApplicationContext 在 BeanFactory 的基础上增加了许多企业级的功能,例如 AOP(面向切面编程)、国际化、事务支持等。

ApplicationContext 接口有两个常用的实现类,具体如下表。

实现类 描述 示例代码
ClassPathXmlApplicationContext 加载类路径 ClassPath 下指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);
FileSystemXmlApplicationContext 加载指定的文件系统路径中指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作 ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

参数 configLocation 用于指定 Spring 配置文件的名称和位置,如 Beans.xml。

演示 ApplicationContext 的使用 

修改 HelloSpring 项目 MainApp 类中 main() 方法的代码,具体代码如下。 

public static void main(String[] args) {
    //使用 FileSystemXmlApplicationContext 加载指定路径下的配置文件 Bean.xml
    BeanFactory context = new FileSystemXmlApplicationContext("D:\\springworkspace\\
HelloSpring\\src\\Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 运行 MainApp.java,控制台输出如下:文章来源地址https://www.toymoban.com/news/detail-641354.html

message : Hello World!

到了这里,关于Spring IoC (控制反转)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring5学习随笔-IOC(反转控制)、DI(依赖注入)和创建复杂对象

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 控制:对于成员变量赋值的控制权 反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中。 好处:解耦合

    2024年02月05日
    浏览(42)
  • 【Spring进阶系列丨第二篇】Spring中的两大核心技术IoC(控制反转)与DI(依赖注入)

    我们都知道Spring 框架主要的优势是在 简化开发 和 框架整合 上,至于如何实现就是我们要学习Spring 框架的主要内容,今天我们就来一起学习Spring中的两大核心技术IoC(控制反转)与DI(依赖注入)。 以经典的三层架构MVC作为案例,以前我们都是这么干的,看如下代码: 按照

    2024年02月05日
    浏览(70)
  • Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC

    Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的 反射机制 。简单来说, 反射机制指的是程序在运行时能够获取自身

    2024年02月09日
    浏览(62)
  • .Net Core后端架构实战【3-介入IOC控制反转】

    摘要:基于.NET Core 7.0WebApi后端架构实战【2-介入IOC控制反转】  2023/04/09, ASP.NET Core 7.0, VS2022 Dependency Injection,何为依赖注入?由容器动态的将对象依赖的资源注入到对象之中。假设容器在构造对象A时,对象A的构造依赖对象B、对象C、对象D这些参数,容器会将这些依赖关系自

    2024年02月07日
    浏览(43)
  • 使用 Spring 实现控制反转和依赖注入

    在本文中,我们将介绍 IoC (控制反转)和 DI (依赖注入)的概念,以及如何在 Spring 框架中实现它们。 控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给容器或框架。我们最常在面向对象编程的上下文中使用它。 与传统编程相比,传统编程中我

    2024年02月13日
    浏览(35)
  • Spring第二讲:SpringIoC控制反转、依赖注入

    4、1什么是IoC 在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。但在 Spring 应用中,Java 对象创建的控制权是掌握在 IoC 容器手里,开发者通过XML或注解的配置将Java对

    2024年02月13日
    浏览(46)
  • Spring学习笔记(二)Spring的控制反转(设计原则)与依赖注入(设计模式)

    是一种设计原则,降低程序代码之间的耦合度 对象由Ioc容器统一管理,当程序需要使用对象时直接从IoC容器中获取。这样对象的控制权就从应用程序转移到了IoC容器 依赖注入是一种消除类之间依赖关系的设计模式。例如,A类要依赖B类,A类不再直接创建B类,而是把这种依赖

    2024年02月19日
    浏览(38)
  • Go中的控制反转 IoC

    控制反转 是一种解耦思想,将原本耦合在 业务逻辑 中的 控制逻辑 单独拆出来实现,不再让 业务逻辑 在处理业务的同时还要去实现 控制逻辑 ,而是专注处理业务。在 业务逻辑 代码中耦合进 控制逻辑 ,会导致在编写业务逻辑时需要处理业务之外的事,而且 控制逻辑 耦合

    2024年03月12日
    浏览(39)
  • IOC控制反转--.net framework

    分层架构: 传统工艺:会有依赖,上端全部展示细节 依赖于抽象:左边依赖倒置,面向抽象 实现类继承接口,实现类实现接口的方法 左边抽象,右边实现类 BaseBll.cs (ZhaoxiFramework.BLL) 调用 第三方工厂 IPhone.cs(ZhaoxiFramework.Interface) ObjectFactory.cs(ZhaoxiFramework.IOC.Project)

    2024年02月16日
    浏览(47)
  • 从依赖倒置原则到IOC控制反转实现

    从依赖倒置原则(Dependency Inversion Principle, DIP)到控制反转(Inversion of Control, IoC)再到依赖注入(Dependency Injection, DI)的演进过程,我们可以理解为一种逐步抽象和解耦的设计思想。这种思想在C#等面向对象的编程语言中得到了广泛的应用。 首先,让我们回顾一下依赖倒置原

    2024年04月24日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包