【Spring】深度剖析IoC

一文彻底搞懂 Spring IoC(概念、原理、实现机制、DI注入、面试重点)


在学习 Spring 时,最核心的两个概念就是:

复制代码
IoC
AOP

几乎所有 Spring 功能都建立在这两个基础之上。

如果说:

复制代码
AOP = 功能增强

那么:

复制代码
IoC = Spring 的核心基础

很多初学者会疑惑:

  • 什么是 IoC?
  • IoC 和 DI 是什么关系?
  • Spring 是如何实现 IoC 的?
  • Spring 容器到底在做什么?
  • @Autowired 是怎么完成注入的?

本篇文章将 系统讲清 Spring IoC 的核心知识体系


一、什么是 IoC

1 IoC 概念

IoC 全称:

复制代码
Inversion of Control
控制反转

简单理解:

复制代码
对象的创建与管理权
从程序员手中
交给 Spring 容器

传统代码:

java 复制代码
UserService userService = new UserService();

对象由开发者创建。

而在 Spring 中:

java 复制代码
@Autowired
UserService userService;

对象由:

复制代码
Spring 容器创建

这就是:

复制代码
控制反转

二、为什么需要 IoC

在传统 Java 开发中:

对象之间会产生大量依赖关系。

例如:

复制代码
Controller
   ↓
Service
   ↓
DAO
   ↓
Database

如果不使用 IoC:

java 复制代码
public class OrderService {

    private PaymentService paymentService = new PaymentService();

}

问题:

复制代码
耦合度高
难以测试
难以维护

如果依赖发生变化:

复制代码
PaymentService → NewPaymentService

就必须修改代码。

而 IoC 通过容器管理对象,实现:

复制代码
解耦

三、什么是 DI(依赖注入)

很多人会混淆:

复制代码
IoC
DI

其实关系是:

复制代码
IoC 是思想
DI 是实现方式

DI 全称:

复制代码
Dependency Injection
依赖注入

例如:

java 复制代码
@Service
public class OrderService {

    @Autowired
    private PaymentService paymentService;

}

Spring 会自动把:

复制代码
PaymentService

注入到:

复制代码
OrderService

中。


四、Spring IoC 容器

IoC 的实现依赖:

复制代码
Spring 容器

Spring 容器负责:

复制代码
创建对象
管理对象
注入依赖
维护生命周期

Spring 中主要有两个容器:

容器 说明
BeanFactory 基础容器
ApplicationContext 高级容器

一般我们使用的是:

复制代码
ApplicationContext

例如:

java 复制代码
ApplicationContext context =
        new AnnotationConfigApplicationContext(AppConfig.class);

五、Spring IoC 工作流程

Spring 启动时会经历:

复制代码
1 扫描 Bean
2 注册 BeanDefinition
3 创建 Bean
4 依赖注入
5 Bean 初始化
6 Bean 放入容器

最终:

复制代码
容器中存储所有 Bean

获取 Bean:

java 复制代码
UserService userService = context.getBean(UserService.class);

六、Spring IoC 的实现原理

很多人会问:

复制代码
@Autowired 是怎么实现注入的?

核心技术其实是:

复制代码
反射

Spring 会在运行时通过反射操作对象字段。

例如一个简化模拟:

java 复制代码
// 简化模拟,实际Spring实现更复杂
Class<?> clazz = OrderService.class;

// 1. 创建实例
OrderService orderService = (OrderService) clazz.newInstance();

// 2. 查找需要注入的字段
Field[] fields = clazz.getDeclaredFields();

for (Field field : fields) {
    if (field.isAnnotationPresent(Autowired.class)) {

        // 3. 获取依赖Bean(假设容器已创建)
        PaymentService paymentService = container.getBean(PaymentService.class);

        // 4. 设置字段可访问(因为paymentService是private的)
        field.setAccessible(true);

        // 5. 执行注入!这是DI的核心动作
        field.set(orderService, paymentService);
    }
}

这个过程就是:

复制代码
依赖注入(DI)

真实 Spring 的实现要复杂得多,但核心思想就是:

复制代码
反射 + 容器管理

七、Bean 的创建方式

Spring 创建 Bean 有多种方式。


1 注解方式(最常用)

java 复制代码
@Component
@Service
@Repository
@Controller

例如:

java 复制代码
@Service
public class UserService {
}

Spring 会自动扫描并注册 Bean。


2 @Bean 配置方式

java 复制代码
@Configuration
public class AppConfig {

    @Bean
    public UserService userService(){
        return new UserService();
    }

}

3 XML 配置(旧方式)

xml 复制代码
<bean id="userService" class="com.demo.UserService"/>

现在基本不再使用。


八、Spring 注入方式

Spring 支持多种注入方式。


1 属性注入(最常用)

java 复制代码
@Autowired
private UserService userService;

2 构造器注入

java 复制代码
public OrderService(UserService userService){
    this.userService = userService;
}

优点:

复制代码
更安全
推荐使用

3 Setter 注入

java 复制代码
@Autowired
public void setUserService(UserService userService){
    this.userService = userService;
}

九、IoC 带来的好处

使用 IoC 后:

1 降低耦合

对象之间不直接创建依赖。


2 易于测试

可以轻松替换实现类。

例如:

复制代码
MockService

3 统一管理对象

对象生命周期由 Spring 管理。


4 支持 AOP

AOP 必须依赖 IoC。


十、Spring IoC 常见问题


1 为什么 @Autowired 有时失效?

原因:

复制代码
对象不是 Spring 管理

例如:

java 复制代码
UserService service = new UserService();

Spring 无法注入。


2 为什么 static 字段无法注入?

例如:

java 复制代码
@Autowired
static UserService userService;

原因:

复制代码
Spring 只管理实例对象

3 Bean 找不到怎么办?

可能原因:

复制代码
没有被扫描
包路径错误
存在多个实现

十一、IoC 与 AOP 的关系

很多人会问:

复制代码
IoC 和 AOP 有什么关系?

关系是:

复制代码
IoC 是基础
AOP 是扩展

AOP 必须依赖:

复制代码
Spring 容器

因为:

复制代码
代理对象需要由容器创建

十二、IoC 面试高频问题


1 什么是 IoC?

答:

复制代码
IoC 是一种设计思想,
将对象创建和管理交给容器完成。

2 IoC 和 DI 的区别?

复制代码
IoC 是思想
DI 是实现方式

3 Spring IoC 容器有哪些?

复制代码
BeanFactory
ApplicationContext

4 Spring 如何实现依赖注入?

核心技术:

复制代码
反射

5 Bean 是什么时候创建的?

默认:

复制代码
容器启动时创建

十三、Spring IoC 总结

Spring IoC 的核心思想:

复制代码
对象的创建与管理
交给 Spring 容器

核心机制:

复制代码
容器 + 反射 + 依赖注入

核心流程:

复制代码
扫描Bean
注册BeanDefinition
创建Bean
依赖注入
初始化
放入容器

理解 IoC 之后,就能理解:

复制代码
Spring 为什么能自动装配
Spring 为什么能管理 Bean
Spring 为什么能实现 AOP

因为这一切都建立在:

复制代码
IoC 容器

之上。

相关推荐
程序员牛奶1 小时前
硬核干货!一口气搞懂 Java AQS
后端
初次攀爬者1 小时前
Spring中Bean的生命周期
后端·spring
程序员JerrySUN2 小时前
别再把 HTTPS 和 OTA 看成两回事:一篇讲透 HTTPS 协议、安全通信机制与 Mender 升级加密链路的完整文章
android·java·开发语言·深度学习·流程图
郝学胜-神的一滴2 小时前
系统设计与面向对象设计:两大设计思想的深度剖析
java·前端·c++·ue5·软件工程
myloveasuka2 小时前
[Java]子类到底能继承父类中的哪些东西?继承中成员变量/方法访问特点---就近原则
java·开发语言
umeelove352 小时前
vscode配置django环境并创建django项目(全图文操作)
java
x-cmd2 小时前
[260307] x-cmd v0.8.6:新增 gpt-5.4 模型支持,sudo/os/hostname/cpu 等模块文档更新
java·数据库·gpt·sudo·x-cmd·googel
PPPPickup2 小时前
深信服公司---java实习生后端一二面询问
java·后端·ai
架构师沉默2 小时前
为什么很多大厂 API 不再使用 PUT 和 DELETE?
java·后端·架构