Spring IOC(控制反转)

IOC 是 Spring 中最核心的概念之一,它是每个想要学习 Spring 框架的人都必须要学习并牢固掌握的知识。本节,我们就针对 Spring 框架中的 IOC 以及与 IOC 相关的概念进行讲解。

IOC(控制反转)

IOC(Inversion of Control 的缩写,译为:控制反转)是一种设计模式,它被用来解决程序中各个组件之间的依赖关系,降低程序的耦合度,提高程序的可维护性和可扩展性。

在传统的 Java 应用程序中,开发人员需要手动创建和管理对象;而在使用 Spring 框架后,IOC 容器会自动管理对象的创建和依赖关系,开发人员只需要提供必要的配置信息,就可以让 Spring 容器自动完成对象的创建和注入。

具体来说,在传统的 Java 应用程序中,当一个 Java 类需要依赖另一个类时,开发人员通常需要使用 new 关键字来手动创建对象,然后在代码中引用它。这种做法会使得代码之间的依赖关系非常紧密,不利于程序的维护和扩展。

而在使用 Spring 框架后,开发人员只需要在 XML 配置文件或注解中进行简单的配置,声明所需的 Java 对象,Spring 容器就会自动完成这些对象实例的创建和管理。当其他 Java 类需要使用这些实例时,只需要在类中声明相应的属性,然后使用 XML 配置文件或注解中指定依赖关系,Spring 容器会自动完成对象的创建和注入。

也就是说,IOC 将对象的创建和管理权,从开发人员手里转移到了 Spring 容器中,这就是所谓的“控制反转”。

总之,IOC 是一种可以让程序的各个组件之间解耦的设计模式,它可以将对象的创建和依赖管理全部交给容器来处理,让开发人员可以更专注于业务逻辑的实现,提高程序的可维护性和可扩展性。

Spring 的 IOC 模式实现主要依赖于两个核心概念:Spring Bean 和 Spring IOC 容器,如下表。

概念 说明
Spring Bean 一个由 Spring IOC容器创建、组装和管理的 Java 对象。在 Spring 中,Bean 是应用程序的基本组件,通过 Bean 可以实现不同对象之间的依赖注入,从而实现松耦合的设计。
Spring IOC 容器 Spring 框架的核心。它是一个容器,用于管理和协调应用程序中所有的 Bean。在应用程序启动时,IOC 容器会读取配置文件中的 Bean 定义,然后根据这些定义创建和管理所有的 Bean 实例。通过 IOC 容器的管理,应用程序可以很方便地实现各种复杂的依赖关系、配置和管理。

DI(依赖注入)

DI 是 Dependency Injection 的缩写,中文含义为“依赖注入”,它是 Spring 框架的核心功能之一。通过 DI,开发人员可以将对象之间的依赖关系交由 Spring 容器来管理和注入,从而实现对象之间的解耦。

在使用 DI 时,开发人员可以通过配置文件或注解等方式来管理对象的依赖项,Spring 容器会根据配置的内容自动创建和注入对象所依赖的属性。这种方式可以避免开发人员手动创建和管理依赖项的问题,让开发人员可以更加专注于业务逻辑的实现。

虽然 DI 和 IOC 的概念看起来十分相似,但它们是有区别的。IOC 是一种更广泛的设计思想,指的是通过将对象的控制权反转到容器中来实现对象之间的解耦。而 DI 是 IOC 的一种实现方式,它通过让 Spring 容器来管理对象之间的依赖关系,实现了 IOC 的设计思想。

因此,DI是Spring框架中用于实现IOC设计思想的一种具体技术,它可以让开发人员将对象之间的依赖关系交由Spring容器来管理,从而提高代码的灵活性和可维护性。

需要注意的是,DI 并不是 Spring 框架所独有的概念,它是一种通用的编程模式。在 DI 的实现中,通常会有一个容器(如 Spring 的 IOC 容器)来管理对象的生命周期和依赖关系。通过 DI,我们可以更加方便地编写可扩展、可测试和可维护的代码。

IOC 容器

前面我们提到,在 DI 的实现中,通常都会有一个容器来管理对象的生命周期和依赖关系。在 Spring 中,这个容器就是 IOC 容器。

IOC 容器是 Spring 框架中的核心组件之一,它的主要作用是管理应用程序中的对象,并负责处理对象之间的依赖关系。IOC 容器是具有生命周期的,它会在应用程序启动时创建,在应用程序关闭时销毁。

在 Spring 框架中,被 IOC 容器管理的 Java 对象被称为 Spring Bean。这些 Spring Bean 在使用起来,与传统的通过 new 关键字创建的普通 Java 对象并没有什么区别;但相比普通的 Java 对象,Spring Bean 则可以受到 IOC 容器的管理和控制,具有更灵活的生命周期和更强的可扩展性。

除了对象的创建和管理,IOC 容器还负责处理对象之间的依赖关系。当一个对象需要依赖其他对象时,IOC 容器会自动将所需的对象注入到该对象中,从而实现依赖注入(DI)。这种方式可以减少对象之间的耦合,使得应用程序更加灵活和可维护。

Spring IOC 容器可以分为两种类型,如下表。

IOC 容器 说明
BeanFactory BeanFactory 是 Spring IOC 容器最基本的形式。它负责创建对象并管理它们之间的依赖关系。

BeanFactory 容器只有在实际需要时才会创建 Bean,因此它具有延迟加载(Lazy-loading)的特点。
ApplicationContext ApplicationContext 是 BeanFactory 的扩展,它提供了更多的功能和特性,例如国际化、资源管理、事件发布、AOP等。

ApplicationContext 在容器启动时就会创建 Bean 实例,并提供了更多的 Bean 生命周期管理特性。

除了以上两种类型,Spring 还提供了其他类型的 IOC 容器,例如:
  • AnnotationConfigApplicationContext:这是一个基于注解的容器,可以通过扫描指定的包或类来自动创建 Bean。
  • ClassPathXmlApplicationContext:这是一个基于 XML 配置文件的容器,可以通过解析配置文件中的 Bean 定义来创建 Bean。
  • FileSystemXmlApplicationContext:这也是一个基于 XML 配置文件的容器,但它使用文件系统路径来加载配置文件。

这些 IOC 容器之间的主要区别在于它们的创建方式和使用场景。例如 AnnotationConfigApplicationContext 可以使用注解配置来自动创建 Bean,而 ClassPathXmlApplicationContext 可以使用 XML 配置文件来定义 Bean。在实际开发中,我们需要根据应用程序的需求以及个人偏好,选择合适的容器。

使用 Spring IOC 容器的一般步骤如下:
  1. 配置 IOC 容器:通过 XML 配置文件、Java 注解或者 Java 配置类等方式,定义需要创建和管理的 Bean、Bean 的依赖关系以及其他相关信息。
  2. 加载 IOC 容器:使用 ApplicationContext 或者 BeanFactory 接口,加载配置好的 Spring IOC 容器。
  3. 使用 IOC 容器:容器加载完成后,通过容器获取托管的 Bean 实例,使用它们完成应用程序的业务逻辑。
  4. 关闭 IOC 容器:在应用程序运行结束时,关闭 Spring IOC 容器,释放资源并关闭与 Bean 相关的活动。

例如,下面是使用 XML 文件配置 Spring IOC 容器的例子。

1. 在 Spring 项目的类路径下(src/main/resouces)创建一个 XML 配置文件,例如 applicationContext.xm,示例配置如下。
<bean id="customerService" class="com.example.CustomerServiceImpl">
   <property name="customerDAO" ref="customerDAO" />
</bean>

<bean id="customerDAO" class="com.example.CustomerDAOImpl" />
在这个配置文件中,我们共定义了两个不同的 Bean,它们的 id 分别为 customerService 和 customerDAO。

2. 接下来,我们就可以在应用程序的代码中来获取 IOC 容器了,示例代码如下。
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

3. 在获取到 IOC 容器的实例之后,下面我们就可以通过 IOC 容器提供的 API 来获取 Bean 实例并使用它们了,示例代码如下。
//获取 IOC 容器中的 Bean 对象
CustomerService customerService = context.getBean("customerService", CustomerService.class);
//直接调用 Bean 对象的方法
customerService.getCustomers();

注意:以上是一种常见的使用 Spring IOC 容器的方式,但是具体的步骤可能因为应用程序的不同而有所不同。

总结

  • IOC 是一种设计模式,通过控制反转来实现对象之间的解耦。
  • DI 是实现 IOC 的一种方式,通过依赖注入来实现对象之间的依赖关系。
  • IOC 容器是 Spring 框架中实现 DI 时的容器,负责创建和管理对象,以及处理对象之间的依赖关系。

关  闭