Spring IoC容器原理深度解析:源码级剖析(通俗易懂版)

一、核心思想:好莱坞原则

“Don’t call us, we’ll call you” - 你不用找对象,对象会来找你
IoC(控制反转)的本质是将对象的创建与依赖关系的控制权从程序员手中转移到容器。想象你点外卖(需要对象)时:

  • 传统方式:你自己买菜、切菜、烹饪(new Object())
  • IoC方式:你只需下单(声明需求),外卖平台(容器)自动配送到家

二、容器核心架构

«interface»
BeanFactory
+getBean(String name) : Object
+isSingleton(String name) : boolean
«interface»
ApplicationContext
+refresh() : void
DefaultListableBeanFactory
-beanDefinitionMap Map
+registerBeanDefinition()
+preInstantiateSingletons()

三、核心实现原理(源码级解析)

1. 存储容器:BeanDefinition注册中心

// DefaultListableBeanFactory.java
private final Map<String, BeanDefinition> beanDefinitionMap 
    = new ConcurrentHashMap<>(256);

每个Bean的定义(BeanDefinition)包括:

  • 类路径(className)
  • 作用域(singleton/prototype)
  • 依赖关系(dependsOn)
  • 初始化/销毁方法

2. 启动流程:容器初始化(refresh方法)

// AbstractApplicationContext.java
public void refresh() {
    // 1. 创建并配置Bean工厂
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    // 2. 加载Bean定义
    loadBeanDefinitions(beanFactory);
    
    // 3. 注册Bean后处理器
    registerBeanPostProcessors(beanFactory);
    
    // 4. 初始化单例Bean (关键步骤!)
    finishBeanFactoryInitialization(beanFactory);
}

3. Bean创建流程(源码级流程)

IoC容器 BeanFactory BeanProcessor Bean 1. getBean("userService") 2. createBeanInstance() 3. populateProperties() 4. postProcessBeforeInitialization() 5. invokeInitMethods() 6. postProcessAfterInitialization() 7. 返回完整Bean IoC容器 BeanFactory BeanProcessor Bean

4. 解决循环依赖(三级缓存机制)

// DefaultSingletonBeanRegistry.java
// 一级缓存:成品Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 

// 二级缓存:半成品Bean(提前暴露)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);  

// 三级缓存:Bean工厂(解决代理问题)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

处理流程:

  1. UserService创建时将自己放入三级缓存(ObjectFactory)
  2. 填充依赖时发现需要RoleService
  3. 创建RoleService时发现需要UserService
  4. 从三级缓存获取UserService的早期代理
  5. 完成RoleService创建,并注入UserService

四、依赖注入的三种方式

1. 字段注入(最常用)

public class UserService {
    @Autowired 
    private UserDao userDao; // 自动注入
}

源码实现:

// AutowiredAnnotationBeanPostProcessor.java
public PropertyValues postProcessPropertyValues(
    PropertyValues pvs, Object bean, String beanName) {
    // 反射获取@Autowired字段
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
    // 执行注入
    metadata.inject(bean, beanName, pvs);
}

2. 构造器注入(推荐)

public class OrderService {
    private PaymentService paymentService;
    
    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

3. Setter方法注入

public class ProductService {
    private StorageService storageService;
    
    @Autowired
    public void setStorageService(StorageService storageService) {
        this.storageService = storageService;
    }
}

五、Bean生命周期管理(关键扩展点)

实例化Bean
填充属性
调用Aware方法
应用前置处理器
调用初始化方法
应用后置处理器
准备就绪
容器关闭
调用销毁方法

核心接口:

  1. BeanPostProcessor:Bean初始化前后回调
    • postProcessBeforeInitialization()
    • postProcessAfterInitialization()
  2. BeanFactoryPostProcessor:Bean定义解析完成后回调
  3. InitializingBean/DisposableBean:初始化/销毁接口

六、容器实现的精华原理

1. 配置解析过程(配置 → BeanDefinition)

配置文件/注解
BeanDefinitionReader
BeanDefinition
BeanDefinition注册中心

2. 单例Bean的延迟初始化(源码级)

// DefaultListableBeanFactory.java
public void preInstantiateSingletons() {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        // 只初始化非懒加载的单例Bean
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            getBean(beanName); // 触发创建
        }
    }
}

3. 动态代理如何融入容器

// AbstractAutoProxyCreator.java(AOP实现核心)
public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (shouldProxy(bean.getClass())) {
        // 创建代理对象
        return wrapIfNecessary(bean, beanName);
    }
    return bean;
}

七、通俗总结:IoC容器的本质

想象Spring容器是个"智能机器人管家"

  1. 你把电器说明书(Bean定义)交给它:
  • “这是个电饭煲类,插电才能用(依赖)”
  1. 管家收集所有说明书建档案库(BeanDefinitionMap)
  2. 当你喊"我要做饭"(getBean(“riceCooker”)):
    • 它先查说明书 → 找到电饭煲类
    • 发现需要电源(依赖)→ 找到"电源"插头
    • 组装好电饭煲(实例化)→ 接好电源线(依赖注入)
    • 按下启动按钮(初始化方法)
  3. 成品电饭煲送到你手里直接使用
  4. 用完喊"收工"(context.close())→ 管家自动断电(销毁)
    整个过程你只需"声明需求",完全不用操心如何组装对象、处理依赖关系,这就是IoC容器的精妙之处!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜雨hiyeyu.com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值