# Spring教程 - 3 IoC容器
Spring 最主要的功能就是提供了 IoC容器
和 AOP面向切面编程
。
先介绍 Ioc 容器。
# 3.1 IoC容器
什么是 IoC 容器?
IoC 就是 Inversion of Control Container
,翻译成中文就是 控制反转。
那什么是控制反转?
在传统 Java 程序中,对象通常自己负责创建它所依赖的其他对象。例如:
class UserService {
private UserRepository userRepo = new UserRepository(); // 自己创建依赖
}
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;
}
}
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 项目中。