# Spring教程 - 3 IoC容器

Spring 最主要的功能就是提供了 IoC容器AOP面向切面编程

先介绍 Ioc 容器。

# 3.1 IoC容器

什么是 IoC 容器?

IoC 就是 Inversion of Control Container,翻译成中文就是 控制反转


那什么是控制反转?

在传统 Java 程序中,对象通常自己负责创建它所依赖的其他对象。例如:

class UserService {
    private UserRepository userRepo = new UserRepository(); // 自己创建依赖
}
1
2
3
  • 在上面的代码中,UserService 依赖 UserRepository,我们会在 UserService 中创建 UserRepository 对象,这种情况下,控制权在对象自身,它决定了依赖关系的创建和管理。

而在 IoC(控制反转) 的思想下,这种控制权被“反转”了,不再由对象自己来控制依赖的创建,而是由外部(比如框架或容器)来负责创建并注入所需的依赖

在 Spring 中,也就是把这种对象创建、依赖关系的管理交给容器(Spring IoC容器)去做,而不是你自己 new


那么如何实现控制反转呢?

这里涉及到另外一个概念:依赖注入(Dependency Injection, DI)

依赖注入(DI)不知道是谁起的高大上的名字,说白了,就是通过构造函数或者Setter 方法,由外部(比如 IoC 容器)调用这些方法,设置对象中的属性而已。

举个栗子:

// 不使用 DI(传统方式)
class UserService {
    private UserRepository userRepo = new UserRepository(); // 自己创建依赖
}

// 使用 DI(推荐方式)
class UserService {
    private UserRepository userRepo;

    // 通过构造函数注入依赖
    public UserService(UserRepository userRepo) {
        this.userRepo = userRepo;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • 在上面的代码中,UserService 不再自己创建 UserRepository,而是 由外部(比如 Spring 容器)创建好 UserRepository 后,传给 UserService。这就是依赖注入,是 IoC 的一种实现方式。

所以说白了,Spring Ioc 容器就是帮我们管理对象创建、处理对象之间依赖关系的工具,容器中的就是 Java对象。不过在 Spring 中,我们叫它们 Spring Bean对象,其实和 Java对象没区别。

总结:IoC 本身是一种思想,而依赖注入是实现 IoC 的一种常见方式。IoC 是思想,DI 是实现思想的方法。


# 3.2 Spring IoC容器

Spring IoC 是按照 IoC 思想实现的一个具体框架。

Spring 提供了两个顶层接口,负责管理 Bean(即 Java 对象)的创建、依赖注入和配置:

  • BeanFactory
  • ApplicationContext

BeanFactory 和 ApplicationContext的对比

特性 BeanFactory ApplicationContext
定位 IoC 容器的基础接口 是 BeanFactory 的子接口,更高级的容器
Bean 加载时机 延迟加载(懒加载),调用 getBean()时才创建 大多数 Bean 默认启动时就初始化(非懒加载)
功能丰富性 基础功能(仅管理 Bean 和依赖) 包含 国际化、事件机制、AOP、注解等企业级功能
使用场景 一般是Spring内部使用的接口,不提供给开发人员使用 开发中推荐使用,几乎所有 Spring 应用都基于它
易用性 较底层,使用麻烦 更方便,支持类型安全的 Bean 获取、注解驱动等

所以我们使用 ApplicationContext 就好了,我们可以通过 ApplicationContext 加载配置,创建Bean、获取Bean等各种操作。


我们在 Helloworld 中,我们就已经使用了 ApplicationContext 实现类,创建了 ApplicationContext,并进行了Bean的创建和获取。

ApplicationContext 常见实现类有:

  • AnnotationConfigApplicationContext : 用于基于 Java 注解的配置(推荐!)
  • ClassPathXmlApplicationContext : 用于基于 XML 的传统配置
  • FileSystemXmlApplicationContext : 从文件系统加载 XML 配置

这里我们是学习 Spring,所以从一些基础的操作开始。其实在正式的项目中,除了特定的场景下,我们一般也不用直接操作ApplicationContext,都是通过配置好了,自动启动加载的,不过不着急,我们慢慢来。


在 Spring 中配置有两种方式,一种是基于 XML 实现,一种是基于注解实现。

下面就依次介绍这两种方式。

现在在项目中,一般都是使用注解的,尤其是在 SpringBoot 项目中。