Spring 源码猎人:从一行代码看框架设计(1)

容器篇:手写一个简化版 IoC 容器,彻底理解 Bean 的来龙去脉

前言:为什么要手写 IoC 容器?

先问一个问题:你觉得自己真的理解 Spring 的 IoC 容器吗?

很多同学学习 Spring 的过程是这样的:

  • 知道 @Component 能把类交给 Spring 管理
  • 会用 @Autowired 自动注入依赖
  • 面试前背过 Bean 的生命周期有几步
  • 遇到问题会 Google 搜索解决方案

但是,当被问到:

BeanDefinition 是什么?它和 Bean 是什么关系?

Spring 是如何扫描包并找到 @Component 的?

@Autowired 的实现原理是什么?

三级缓存是如何解决循环依赖的?

很多人就开始含糊了。

为什么会出现这种情况?

因为我们在"使用"框架,而不是在"理解"框架。Spring 对我们来说就像一个黑盒——输入注解,输出 Bean,中间的过程是"魔法"。

如何才能打破这个黑盒?

最有效的方法就是:亲手实现一个简化版的 IoC 容器。

这就是本文的目的。我们将从零开始,一行一行代码实现一个 Mini-IoC 容器,包含:

  • Bean 的定义与注册
  • 单例 Bean 的缓存管理
  • 依赖注入(自动装配)
  • BeanPostProcessor 扩展点
  • 完整的生命周期管理

当我们亲手写出这些代码后,再去阅读 Spring 源码,就会发现:原来 Spring 就是这么做的,只不过它做得更完善、更健壮、更灵活。


第一部分:IoC 容器的本质是什么?

1.1 从使用者的视角看 IoC

在传统编程中,对象自己负责创建依赖:

public class OrderService {
    private UserService userService;
    
    public OrderService() {
        // 自己创建依赖
        this.userService = new UserService();
    }
}

在 Spring 的 IoC 容器中,对象不再自己创建依赖,而是被动接收:

public class OrderService {
    private UserService userService;
    
    public OrderService(UserService userService) {
        // 别人创建好传给我
        this.userService = userService;
    }
}

1.2 从实现者的视角看 IoC

那么,这个"别人"——IoC 容器——到底长什么样?

IoC 容器的本质是一个 Map,一个存储和管理对象的工厂。

// 最简化的 IoC 容器
public class SimpleIocContainer {
    // key: beanName, value: bean 实例
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    // 根据名称获取 Bean
    public Object getBean(String name) {
        return singletonObjects.get(name);
    }
    
    // 注册 Bean
    public void registerBean(String name, Object bean) {
        singletonObjects.put(name, bean);
    }
}

就这么简单?对,这就是 IoC 容器的核心模型

当然,真正的 Spring 容器远比这复杂,因为它需要解决:

  • Bean 的定义从哪里来?(XML、注解、Java Config)
  • Bean 如何创建?(构造器、工厂方法)
  • 依赖如何自动注入?(类型匹配、名称匹配)
  • Bean 如何管理生命周期?(初始化、销毁)
  • 如何处理复杂配置?(作用域、懒加载、条件化)

接下来,我们就一步步完善这个容器。


第二部分:从零开始——定义 Bean 和 BeanDefinition

2.1 Bean 与 BeanDefinition 的关系

在 Spring 中,BeanDefinitionBean 是两个不同的概念:

  • BeanDefinition:Bean 的"配方"或"设计图",描述 Bean 如何创建
  • Bean:根据配方创建出来的"产品",是真正的实例
// Bean 的定义(配方)
public class BeanDefinition {
    private Class<?> beanClass;           // Bean 的类型
    private String scope;                  // 作用域(singleton/prototype)
    private boolean lazyInit;               // 是否懒加载
    private Map<String, Object> properties; // 属性值
    // ... 其他配置
}

// Bean 的实例(产品)
Object bean = beanDefinition.getBeanClass().newInstance();

2.2 实现我们的 BeanDefinition

package com.mini.spring.beans;

/**
 * Bean 定义——描述 Bean 的元数据
 */
public class BeanDefinition {
    
    // Bean 的类类型
    private Class<?> beanClass;
    
    // 作用域:singleton 或 prototype
    private String scope = "singleton";
    
    // 是否懒加载
    private boolean lazyInit = false;
    
    // 属性值(用于依赖注入)
    private Map<String, Object> propertyValues = new HashMap<>();
    
    // 初始化方法名(对应 @PostConstruct 或 init-method)
    private String initMethodName;
    
    // 销毁方法名(对应 @PreDestroy 或 destroy-method)
    private String destroyMethodName;
    
    // 构造函数
    public BeanDefinition(Class<?> beanClass) {
        this.beanClass = beanClass;
    }
    
    // getters and setters
    public Class<?> getBeanClass() {
        return beanClass;
    }
    
    public String getScope() {
        return scope;
    }
    
    public void setScope(String scope) {
        this.scope = scope;
    }
    
    public boolean isSingleton() {
        return "singleton".equals(scope);
    }
    
    public boolean isPrototype() {
        return "prototype".equals(scope);
    }
    
    public boolean isLazyInit() {
        return lazyInit;
    }
    
    public void setLazyInit(boolean lazyInit) {
        this.lazyInit = lazyInit;
    }
    
    public Map<String, Object> getPropertyValues() {
        return propertyValues;
    }
    
    public void addPropertyValue(String name, Object value) {
        propertyValues.put(name, value);
    }
    
    public String getInitMethodName() {
        return initMethodName;
    }
    
    public void setInitMethodName(String initMethodName) {
        this.initMethodName = initMethodName;
    }
    
    public String getDestroyMethodName() {
        return destroyMethodName;
    }
    
    public void setDestroyMethodName(String destroyMethodName) {
        this.destroyMethodName = destroyMethodName;
    }
}

第三部分:容器的核心——注册与获取

3.1 容器接口设计

首先,定义容器的核心接口:

package com.mini.spring.beans.factory;

/**
 * Bean 容器顶层接口
 */
public interface BeanFactory {
    
    /**
     * 根据名称获取 Bean
     */
    Object getBean(String name) throws Exception;
    
    /**
     * 根据名称和类型获取 Bean
     */
    <T> T getBean(String name, Class<T> requiredType) throws Exception;
    
    /**
     * 根据类型获取 Bean
     */
    <T> T getBean(Class<T> requiredType) throws Exception;
    
    /**
     * 是否包含 Bean
     */
    boolean containsBean(String name);
    
    /**
     * 判断 Bean 是否为单例
     */
    boolean isSingleton(String name);
    
    /**
     * 判断 Bean 是否为原型
     */
    boolean isPrototype(String name);
}

3.2 核心容器实现

package com.mini.spring.beans.factory.support;

import com.mini.spring.beans.BeanDefinition;
import com.mini.spring.beans.factory.BeanFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认 Bean 工厂实现
 */
public class DefaultBeanFactory implements BeanFactory {
    
    // Bean 定义注册表:key = beanName, value = BeanDefinition
    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    
    // 单例 Bean 缓存:key = beanName, value = bean 实例
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    /**
     * 注册 Bean 定义
     */
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }
    
    @Override
    public Object getBean(String name) throws Exception {
        // 1. 先从单例缓存中获取
        Object bean = singletonObjects.get(name);
        if (bean != null) {
            return bean;
        }
        
        // 2. 获取 Bean 定义
        BeanDefinition beanDefinition = beanDefinitionMap.get(name);
        if (beanDefinition == null) {
            throw new Exception("No bean named '" + name + "' is defined");
        }
        
        // 3. 创建 Bean 实例
        bean = createBean(beanDefinition);
        
        // 4. 如果是单例,放入缓存
        if (beanDefinition.isSingleton()) {
            singletonObjects.put(name, bean);
        }
        
        return bean;
    }
    
    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws Exception {
        Object bean = getBean(name);
        if (requiredType != null && !requiredType.isInstance(bean)) {
            throw new Exception("Bean named '" + name + "' is not of type " + requiredType);
        }
        return (T) bean;
    }
    
    @Override
    public <T> T getBean(Class<T> requiredType) throws Exception {
        // 根据类型查找 Bean(简化实现:找到第一个匹配的)
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            if (requiredType.isAssignableFrom(entry.getValue().getBeanClass())) {
                return getBean(entry.getKey(), requiredType);
            }
        }
        throw new Exception("No bean of type " + requiredType + " is defined");
    }
    
    @Override
    public boolean containsBean(String name) {
        return beanDefinitionMap.containsKey(name);
    }
    
    @Override
    public boolean isSingleton(String name) {
        BeanDefinition bd = beanDefinitionMap.get(name);
        return bd != null && bd.isSingleton();
    }
    
    @Override
    public boolean isPrototype(String name) {
        BeanDefinition bd = beanDefinitionMap.get(name);
        return bd != null && bd.isPrototype();
    }
    
    /**
     * 创建 Bean 实例
     */
    private Object createBean(BeanDefinition beanDefinition) throws Exception {
        // 1. 实例化
        Object bean = beanDefinition.getBeanClass().newInstance();
        
        // 2. 属性填充(依赖注入)- 下一节实现
        // populateBean(bean, beanDefinition);
        
        // 3. 初始化
        // initializeBean(bean, beanDefinition);
        
        return bean;
    }
}

3.3 测试我们的容器

public class MiniIocTest {
    
    public static void main(String[] args) throws Exception {
        // 1. 创建容器
        DefaultBeanFactory factory = new DefaultBeanFactory();
        
        // 2. 注册 Bean 定义
        BeanDefinition userServiceDef = new BeanDefinition(UserService.class);
        factory.registerBeanDefinition("userService", userServiceDef);
        
        BeanDefinition orderServiceDef = new BeanDefinition(OrderService.class);
        factory.registerBeanDefinition("orderService", orderServiceDef);
        
        // 3. 获取 Bean
        UserService userService = factory.getBean("userService", UserService.class);
        OrderService orderService = factory.getBean("orderService", OrderService.class);
        
        // 4. 验证
        System.out.println(userService);
        System.out.println(orderService);
        
        // 5. 验证单例特性
        UserService userService2 = factory.getBean("userService", UserService.class);
        System.out.println("是否是同一个实例:" + (userService == userService2)); // true
    }
}

// 测试用的 Bean
class UserService {
    public void sayHello() {
        System.out.println("UserService says hello");
    }
}

class OrderService {
    public void sayHello() {
        System.out.println("OrderService says hello");
    }
}

运行结果:

com.mini.spring.test.UserService@1b6d3586
com.mini.spring.test.OrderService@4554617c
是否是同一个实例:true

恭喜!我们已经实现了一个最基础的 IoC 容器——能够注册 Bean 定义、创建实例、缓存单例。


第四部分:单例 Bean 的实现与缓存

4.1 Spring 的单例缓存设计

在 Spring 中,单例 Bean 的缓存不是简单的 Map,而是一套复杂的三级缓存机制:

public class DefaultSingletonBeanRegistry {
    // 一级缓存:成品,完全初始化好的 Bean
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    // 二级缓存:半成品,已经实例化但未初始化的 Bean
    private Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
    
    // 三级缓存:单例工厂,用于生成 Bean 的早期引用
    private Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();
}

为什么需要三级缓存?—— 为了解决循环依赖

4.2 在我们的容器中实现单例缓存

虽然现在还没处理循环依赖,但我们可以先实现基础的单例缓存:

package com.mini.spring.beans.factory.support;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 单例 Bean 注册表基类
 */
public class DefaultSingletonBeanRegistry {
    
    // 一级缓存:成品 Bean
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    // 正在创建中的 Bean 名称集合(用于检测循环依赖)
    private Set<String> singletonsCurrentlyInCreation = 
        Collections.newSetFromMap(new ConcurrentHashMap<>());
    
    /**
     * 获取单例 Bean
     */
    protected Object getSingleton(String beanName) {
        // 1. 从一级缓存获取
        Object singletonObject = singletonObjects.get(beanName);
        return singletonObject;
    }
    
    /**
     * 注册单例 Bean
     */
    protected void addSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }
    
    /**
     * 标记 Bean 正在创建
     */
    protected void beforeSingletonCreation(String beanName) {
        if (!singletonsCurrentlyInCreation.add(beanName)) {
            throw new RuntimeException("循环依赖 detected: " + beanName);
        }
    }
    
    /**
     * 标记 Bean 创建完成
     */
    protected void afterSingletonCreation(String beanName) {
        singletonsCurrentlyInCreation.remove(beanName);
    }
    
    /**
     * 是否正在创建中
     */
    protected boolean isSingletonCurrentlyInCreation(String beanName) {
        return singletonsCurrentlyInCreation.contains(beanName);
    }
}

修改 DefaultBeanFactory,继承这个类:

public class DefaultBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    // ... 其他代码
    
    @Override
    public Object getBean(String name) throws Exception {
        // 1. 先从单例缓存中获取
        Object bean = getSingleton(name);
        if (bean != null) {
            return bean;
        }
        
        // 2. 获取 Bean 定义
        BeanDefinition beanDefinition = beanDefinitionMap.get(name);
        if (beanDefinition == null) {
            throw new Exception("No bean named '" + name + "' is defined");
        }
        
        // 3. 标记 Bean 正在创建
        beforeSingletonCreation(name);
        
        try {
            // 4. 创建 Bean 实例
            bean = createBean(beanDefinition);
            
            // 5. 如果是单例,放入缓存
            if (beanDefinition.isSingleton()) {
                addSingleton(name, bean);
            }
        } finally {
            // 6. 移除创建标记
            afterSingletonCreation(name);
        }
        
        return bean;
    }
}

第五部分:依赖注入——自动装配的实现

5.1 如何识别需要注入的字段

在 Spring 中,我们用 @Autowired 标记需要注入的字段。在我们的 Mini 容器中,我们用自定义注解 @MiniAutowired 来模拟:

package com.mini.spring.beans.annotation;

import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MiniAutowired {
    boolean required() default true;
}

5.2 实现属性填充

我们需要在 createBean 方法中添加属性填充的逻辑:

private Object createBean(BeanDefinition beanDefinition) throws Exception {
    // 1. 实例化
    Object bean = beanDefinition.getBeanClass().newInstance();
    
    // 2. 属性填充(依赖注入)
    populateBean(bean, beanDefinition);
    
    // 3. 初始化(下一节实现)
    // initializeBean(bean, beanDefinition);
    
    return bean;
}

/**
 * 属性填充(依赖注入)
 */
private void populateBean(Object bean, BeanDefinition beanDefinition) throws Exception {
    Class<?> beanClass = bean.getClass();
    
    // 遍历所有字段
    for (Field field : beanClass.getDeclaredFields()) {
        MiniAutowired autowired = field.getAnnotation(MiniAutowired.class);
        if (autowired != null) {
            // 需要注入的字段
            field.setAccessible(true);
            
            // 根据字段类型获取依赖 Bean
            Object dependency = getBean(field.getType());
            
            // 设置字段值
            field.set(bean, dependency);
        }
    }
}

5.3 根据类型查找 Bean

我们需要实现根据类型查找 Bean 的功能:

private Object getBean(Class<?> type) throws Exception {
    // 根据类型查找匹配的 Bean
    for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
        BeanDefinition bd = entry.getValue();
        if (type.isAssignableFrom(bd.getBeanClass())) {
            return getBean(entry.getKey());
        }
    }
    
    // 如果没找到且是 required 的,抛出异常
    throw new Exception("No qualifying bean of type '" + type + "' available");
}

5.4 测试依赖注入

public class DependencyInjectionTest {
    
    public static void main(String[] args) throws Exception {
        // 1. 创建容器
        DefaultBeanFactory factory = new DefaultBeanFactory();
        
        // 2. 注册 Bean 定义
        factory.registerBeanDefinition("userService", new BeanDefinition(UserService.class));
        factory.registerBeanDefinition("orderService", new BeanDefinition(OrderService.class));
        
        // 3. 获取 OrderService
        OrderService orderService = factory.getBean("orderService", OrderService.class);
        
        // 4. 验证依赖是否注入成功
        orderService.placeOrder();
    }
}

class UserService {
    public String getUserName() {
        return "张三";
    }
}

class OrderService {
    
    @MiniAutowired
    private UserService userService;
    
    public void placeOrder() {
        System.out.println("为用户 " + userService.getUserName() + " 创建订单");
    }
}

运行结果:

为用户 张三 创建订单

成功!我们的容器已经能够自动注入依赖了。


第六部分:BeanPostProcessor——Spring 的魔法之源

6.1 什么是 BeanPostProcessor?

BeanPostProcessor 是 Spring 最强大的扩展点之一。它允许我们在 Bean 初始化前后插入自定义逻辑。

Spring 的很多功能都是通过 BeanPostProcessor 实现的:

  • AOP:通过 AbstractAutoProxyCreator 创建代理对象
  • @Autowired:通过 AutowiredAnnotationBeanPostProcessor 处理
  • @PostConstruct:通过 CommonAnnotationBeanPostProcessor 处理

6.2 定义 BeanPostProcessor 接口

package com.mini.spring.beans.factory.config;

/**
 * Bean 后处理器:允许在 Bean 初始化前后进行自定义处理
 */
public interface BeanPostProcessor {
    
    /**
     * 在 Bean 初始化之前执行
     */
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    
    /**
     * 在 Bean 初始化之后执行
     */
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

6.3 实现一个简单的后处理器

package com.mini.spring.test;

import com.mini.spring.beans.factory.config.BeanPostProcessor;

/**
 * 日志后处理器:在 Bean 初始化前后打印日志
 */
public class LogBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("【Log】Bean '" + beanName + "' 初始化前");
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("【Log】Bean '" + beanName + "' 初始化后");
        return bean;
    }
}

6.4 在容器中集成 BeanPostProcessor

修改容器,添加对 BeanPostProcessor 的支持:

public class DefaultBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    
    // Bean 定义映射
    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    
    // 存储所有的 BeanPostProcessor
    private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    
    /**
     * 注册 Bean 定义
     */
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
        
        // 如果这个 Bean 是 BeanPostProcessor 类型,立即实例化并添加到列表
        if (BeanPostProcessor.class.isAssignableFrom(beanDefinition.getBeanClass())) {
            try {
                BeanPostProcessor processor = (BeanPostProcessor) 
                    beanDefinition.getBeanClass().newInstance();
                beanPostProcessors.add(processor);
            } catch (Exception e) {
                throw new RuntimeException("Failed to instantiate BeanPostProcessor", e);
            }
        }
    }
    
    /**
     * 应用 BeanPostProcessor 的 before 方法
     */
    private Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName) {
        Object result = bean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                break;
            }
        }
        return result;
    }
    
    /**
     * 应用 BeanPostProcessor 的 after 方法
     */
    private Object applyBeanPostProcessorsAfterInitialization(Object bean, String beanName) {
        Object result = bean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessAfterInitialization(result, beanName);
            if (result == null) {
                break;
            }
        }
        return result;
    }
    
    /**
     * 创建 Bean 实例(增强版)
     */
    private Object createBean(BeanDefinition beanDefinition) throws Exception {
        String beanName = getBeanName(beanDefinition); // 简化:需要传入 beanName
        
        // 1. 实例化
        Object bean = beanDefinition.getBeanClass().newInstance();
        
        // 2. 属性填充
        populateBean(bean, beanDefinition);
        
        // 3. 初始化前(BeanPostProcessor before)
        bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        
        // 4. 初始化
        initializeBean(bean, beanDefinition);
        
        // 5. 初始化后(BeanPostProcessor after)
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        
        return bean;
    }
    
    /**
     * 初始化 Bean
     */
    private void initializeBean(Object bean, BeanDefinition beanDefinition) throws Exception {
        // 执行 init-method
        if (beanDefinition.getInitMethodName() != null) {
            Method initMethod = bean.getClass().getMethod(beanDefinition.getInitMethodName());
            initMethod.invoke(bean);
        }
    }
    
    // ... 其他方法
}

6.5 测试 BeanPostProcessor

public class BeanPostProcessorTest {
    
    public static void main(String[] args) throws Exception {
        // 1. 创建容器
        DefaultBeanFactory factory = new DefaultBeanFactory();
        
        // 2. 注册 Bean 定义
        BeanDefinition userServiceDef = new BeanDefinition(UserService.class);
        userServiceDef.setInitMethodName("init");
        factory.registerBeanDefinition("userService", userServiceDef);
        
        // 3. 注册 BeanPostProcessor
        BeanDefinition processorDef = new BeanDefinition(LogBeanPostProcessor.class);
        factory.registerBeanDefinition("logProcessor", processorDef);
        
        // 4. 获取 Bean
        UserService userService = factory.getBean("userService", UserService.class);
        userService.sayHello();
    }
}

class UserService {
    
    public void init() {
        System.out.println("【UserService】执行 init 方法");
    }
    
    public void sayHello() {
        System.out.println("Hello from UserService");
    }
}

运行结果:

【Log】Bean 'userService' 初始化前
【UserService】执行 init 方法
【Log】Bean 'userService' 初始化后
Hello from UserService

完美!我们的容器已经支持在 Bean 初始化前后插入自定义逻辑了。


第七部分:完整的 Mini-IoC 容器实现

现在,让我们把所有组件整合起来,形成一个完整的 Mini-IoC 容器。

7.1 项目结构

com.mini.spring/
├── beans/
│   ├── BeanDefinition.java
│   ├── BeansException.java
│   └── annotation/
│       └── MiniAutowired.java
├── beans/factory/
│   ├── BeanFactory.java
│   └── config/
│       ├── BeanPostProcessor.java
│       └── SingletonBeanRegistry.java
└── beans/factory/support/
    ├── DefaultBeanFactory.java
    ├── DefaultSingletonBeanRegistry.java
    └── AbstractBeanFactory.java

7.2 完整的 DefaultBeanFactory 实现

package com.mini.spring.beans.factory.support;

import com.mini.spring.beans.BeanDefinition;
import com.mini.spring.beans.BeansException;
import com.mini.spring.beans.annotation.MiniAutowired;
import com.mini.spring.beans.factory.BeanFactory;
import com.mini.spring.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认 Bean 工厂完整实现
 */
public class DefaultBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    
    // Bean 定义映射
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    
    // BeanPostProcessor 列表
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    
    // 正在创建中的 Bean 名称
    private final ThreadLocal<Set<String>> currentlyCreatingBeanNames = 
        ThreadLocal.withInitial(HashSet::new);
    
    /**
     * 注册 Bean 定义
     */
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
        
        // 如果是 BeanPostProcessor,立即实例化并注册
        if (BeanPostProcessor.class.isAssignableFrom(beanDefinition.getBeanClass())) {
            try {
                BeanPostProcessor processor = (BeanPostProcessor) 
                    beanDefinition.getBeanClass().newInstance();
                beanPostProcessors.add(processor);
            } catch (Exception e) {
                throw new BeansException("Failed to instantiate BeanPostProcessor: " + beanName, e);
            }
        }
    }
    
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null);
    }
    
    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        Object bean = doGetBean(name, requiredType, null);
        return requiredType.cast(bean);
    }
    
    @Override
    public <T> T getBean(Class<T> requiredType) throws BeansException {
        // 根据类型查找 Bean 名称
        String beanName = getBeanNameByType(requiredType);
        if (beanName == null) {
            throw new BeansException("No bean of type " + requiredType + " found");
        }
        return getBean(beanName, requiredType);
    }
    
    @Override
    public boolean containsBean(String name) {
        return beanDefinitionMap.containsKey(name);
    }
    
    @Override
    public boolean isSingleton(String name) {
        BeanDefinition bd = beanDefinitionMap.get(name);
        return bd != null && bd.isSingleton();
    }
    
    @Override
    public boolean isPrototype(String name) {
        BeanDefinition bd = beanDefinitionMap.get(name);
        return bd != null && bd.isPrototype();
    }
    
    /**
     * 核心方法:获取 Bean
     */
    private Object doGetBean(String beanName, Class<?> requiredType, Object[] args) {
        // 1. 从单例缓存中获取
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null) {
            return getObjectForBeanInstance(sharedInstance, beanName);
        }
        
        // 2. 检查 Bean 定义是否存在
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new BeansException("No bean named '" + beanName + "' is defined");
        }
        
        // 3. 标记当前正在创建的 Bean(用于检测循环依赖)
        Set<String> creatingSet = currentlyCreatingBeanNames.get();
        if (creatingSet.contains(beanName)) {
            throw new BeansException("Circular dependency detected: " + beanName);
        }
        creatingSet.add(beanName);
        
        try {
            // 4. 创建 Bean
            Object bean = createBean(beanName, beanDefinition, args);
            
            // 5. 如果是单例,放入缓存
            if (beanDefinition.isSingleton()) {
                addSingleton(beanName, bean);
            }
            
            return getObjectForBeanInstance(bean, beanName);
        } finally {
            creatingSet.remove(beanName);
            if (creatingSet.isEmpty()) {
                currentlyCreatingBeanNames.remove();
            }
        }
    }
    
    /**
     * 创建 Bean
     */
    private Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {
        try {
            // 1. 实例化
            Object bean = instantiateBean(beanDefinition, args);
            
            // 2. 提前暴露(用于解决循环依赖)
            if (beanDefinition.isSingleton()) {
                addEarlySingleton(beanName, bean);
            }
            
            // 3. 属性填充(依赖注入)
            populateBean(bean, beanDefinition);
            
            // 4. 初始化
            bean = initializeBean(bean, beanName, beanDefinition);
            
            return bean;
        } catch (Exception e) {
            throw new BeansException("Failed to create bean: " + beanName, e);
        }
    }
    
    /**
     * 实例化 Bean
     */
    private Object instantiateBean(BeanDefinition beanDefinition, Object[] args) throws Exception {
        Class<?> beanClass = beanDefinition.getBeanClass();
        
        // 如果有构造函数参数,使用带参构造(简化实现)
        if (args != null && args.length > 0) {
            Class<?>[] paramTypes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                paramTypes[i] = args[i].getClass();
            }
            return beanClass.getConstructor(paramTypes).newInstance(args);
        }
        
        // 默认使用无参构造
        return beanClass.newInstance();
    }
    
    /**
     * 属性填充(依赖注入)
     */
    private void populateBean(Object bean, BeanDefinition beanDefinition) throws Exception {
        Class<?> beanClass = bean.getClass();
        
        for (Field field : beanClass.getDeclaredFields()) {
            MiniAutowired autowired = field.getAnnotation(MiniAutowired.class);
            if (autowired != null) {
                field.setAccessible(true);
                
                // 根据字段类型获取依赖 Bean
                Object dependency = resolveDependency(field.getType());
                if (dependency == null && autowired.required()) {
                    throw new BeansException("No qualifying bean of type " + field.getType() + 
                                           " found for field " + field.getName());
                }
                
                if (dependency != null) {
                    field.set(bean, dependency);
                }
            }
        }
    }
    
    /**
     * 解析依赖
     */
    private Object resolveDependency(Class<?> type) {
        // 1. 根据类型查找 Bean
        String beanName = getBeanNameByType(type);
        if (beanName != null) {
            return doGetBean(beanName, type, null);
        }
        return null;
    }
    
    /**
     * 初始化 Bean
     */
    private Object initializeBean(Object bean, String beanName, BeanDefinition beanDefinition) 
            throws Exception {
        
        // 1. 应用 BeanPostProcessor before
        Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        
        // 2. 执行初始化方法
        invokeInitMethods(wrappedBean, beanDefinition);
        
        // 3. 应用 BeanPostProcessor after
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        
        return wrappedBean;
    }
    
    /**
     * 执行初始化方法
     */
    private void invokeInitMethods(Object bean, BeanDefinition beanDefinition) throws Exception {
        String initMethodName = beanDefinition.getInitMethodName();
        if (initMethodName != null && !initMethodName.isEmpty()) {
            Method initMethod = bean.getClass().getMethod(initMethodName);
            initMethod.invoke(bean);
        }
    }
    
    /**
     * 应用 BeanPostProcessor before
     */
    private Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName) {
        Object result = bean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                break;
            }
        }
        return result;
    }
    
    /**
     * 应用 BeanPostProcessor after
     */
    private Object applyBeanPostProcessorsAfterInitialization(Object bean, String beanName) {
        Object result = bean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessAfterInitialization(result, beanName);
            if (result == null) {
                break;
            }
        }
        return result;
    }
    
    /**
     * 根据类型获取 Bean 名称
     */
    private String getBeanNameByType(Class<?> type) {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            if (type.isAssignableFrom(entry.getValue().getBeanClass())) {
                return entry.getKey();
            }
        }
        return null;
    }
    
    /**
     * 获取 Bean 实例(处理 FactoryBean 等情况)
     */
    private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
        // 暂不处理 FactoryBean
        return beanInstance;
    }
}

第八部分:源码对比——我们的容器与 Spring 差在哪?

现在我们已经实现了一个功能完整的 Mini-IoC 容器。让我们对比一下真正的 Spring 源码,看看差距在哪里:

8.1 核心类对应关系

我们的实现 Spring 对应类 差异说明
BeanDefinition GenericBeanDefinition Spring 有完整的 BeanDefinition 继承体系
DefaultBeanFactory DefaultListableBeanFactory Spring 实现了更多接口,功能更丰富
DefaultSingletonBeanRegistry 同名类 Spring 的实现更复杂,包含三级缓存
BeanPostProcessor 同名接口 完全一致的概念
MiniAutowired @Autowired Spring 支持字段、方法、构造器注入

8.2 我们缺少的核心功能

  1. 完整的 BeanDefinition 体系

    • Spring 有 BeanDefinitionReader 读取不同配置源
    • 支持 XML、注解、Java Config 等多种配置方式
  2. 复杂的依赖解析

    • 支持 @Qualifier 按名称注入
    • 支持 @Primary 解决歧义
    • 支持 @Resource 等 JSR-250 注解
  3. 三级缓存解决循环依赖

    • 我们只检测到了循环依赖,但没解决
    • Spring 的三级缓存可以解决 setter 注入的循环依赖
  4. 完整的生命周期管理

    • Spring 有完整的 Aware 接口体系
    • 支持 @PostConstruct@PreDestroy
    • 支持 InitializingBeanDisposableBean
  5. 作用域支持

    • 我们只实现了 singleton 和 prototype
    • Spring 还支持 request、session、application 等
  6. FactoryBean 机制

    • 允许通过工厂方法创建复杂的 Bean
    • 我们的容器暂不支持
  7. 条件化配置

    • @Conditional 及其派生注解
    • @Profile 环境切换
  8. 国际化支持

    • MessageSource 体系

8.3 Spring 源码的精髓

通过对比,我们更能体会到 Spring 源码的精髓:

// Spring 源码中,一个 getBean 方法就包含了完整的处理逻辑
public Object getBean(String name) throws BeansException {
    // 1. 转换 Bean 名称(处理 & 前缀)
    String beanName = transformedBeanName(name);
    
    // 2. 从单例缓存中获取
    Object sharedInstance = getSingleton(beanName);
    
    // 3. 如果是 FactoryBean,特殊处理
    if (sharedInstance != null) {
        return getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    
    // 4. 处理循环依赖(通过 alreadyCreated 集合)
    if (isPrototypeCurrentlyInCreation(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
    
    // 5. 检查父容器
    BeanFactory parentBeanFactory = getParentBeanFactory();
    
    // 6. 标记正在创建
    beforePrototypeCreation(beanName);
    
    try {
        // 7. 创建 Bean
        return createBean(beanName, mbd, args);
    } finally {
        afterPrototypeCreation(beanName);
    }
}

Spring 的每个方法都经过精心设计,考虑到了各种边界情况、性能优化和扩展性。


第九部分:总结与下期预告

9.1 本节核心要点

知识点 核心内容 对应代码
BeanDefinition Bean 的元数据描述 BeanDefinition.java
BeanFactory 容器的核心接口 BeanFactory.java
单例缓存 管理单例 Bean 的 Map singletonObjects
依赖注入 通过反射设置字段值 populateBean()
BeanPostProcessor 初始化前后的扩展点 BeanPostProcessor.java
生命周期 实例化 → 注入 → 初始化 createBean() 方法

9.2 一图胜千言:Mini-IoC 容器全景图

┌─────────────────────────────────────────────────────────────────┐
│                      Mini-IoC 容器全景图                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  【注册阶段】                                                     │
│  BeanDefinition ← 手动注册                                        │
│         ↓                                                        │
│  【获取阶段】                                                     │
│  getBean() 调用                                                   │
│         ↓                                                        │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                 Bean 创建流程                             │    │
│  │  1. 从单例缓存获取 (getSingleton)                         │    │
│  │  2. 如果没有,开始创建 (createBean)                        │    │
│  │     ├─ 2.1 实例化 (instantiateBean)                       │    │
│  │     ├─ 2.2 提前暴露 (addEarlySingleton)                   │    │
│  │     ├─ 2.3 属性填充 (populateBean)                        │    │
│  │     ├─ 2.4 BeanPostProcessor before                       │    │
│  │     ├─ 2.5 初始化方法 (invokeInitMethods)                 │    │
│  │     └─ 2.6 BeanPostProcessor after                        │    │
│  │  3. 放入单例缓存 (addSingleton)                            │    │
│  └─────────────────────────────────────────────────────────┘    │
│         ↓                                                        │
│  返回可用的 Bean 实例                                             │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘

9.3 与 Spring 源码的对应关系

通过亲手实现 Mini-IoC 容器,我们已经掌握了 Spring 容器的核心脉络。接下来,当你去阅读 Spring 源码时,会发现很多熟悉的影子:

  • DefaultListableBeanFactory → 我们的 DefaultBeanFactory
  • AbstractBeanFactorydoGetBean → 我们的 doGetBean
  • AbstractAutowireCapableBeanFactorycreateBean → 我们的 createBean
  • AutowiredAnnotationBeanPostProcessor → 我们的 @MiniAutowired 处理逻辑

9.4 下期预告

下一期,我们将深入 Spring 最难啃的骨头——循环依赖

我们将:

  • 用 Debug 的方式追踪 Spring 的三级缓存是如何工作的
  • 手写代码复现循环依赖的场景
  • 深入源码分析为什么三级缓存能解决 setter 注入的循环依赖,却不能解决构造器注入的循环依赖
  • 探究 Spring 的设计者在面对这个经典问题时的权衡与思考

敬请期待:《Spring 源码猎人(2):三级缓存——Spring 如何解决循环依赖》


动手挑战

学完本文,建议你动手尝试:

  1. 扩展我们的容器:添加对 @Resource 注解的支持
  2. 实现 FactoryBean:让容器能够处理特殊的工厂 Bean
  3. 尝试 Debug Spring 源码:找到 AbstractBeanFactory.doGetBean 方法,跟踪一次完整的 Bean 创建过程

遇到问题时,欢迎在评论区留言交流!

写在最后

很多人问我:“为什么要手写框架?直接用不就好了吗?”

我的回答是:理解底层原理,不是为了让每个人都能写框架,而是为了在遇到问题时能快速定位,在使用时能得心应手。

当你亲手实现了 IoC 容器的核心逻辑后,再去使用 Spring:

  • 你不会再对 @Autowired 感到神秘
  • 你不会再对 Bean 的生命周期感到困惑
  • 你不会再对循环依赖的错误感到束手无策
  • 你会在面试时从容地回答源码层面的问题

这就是"从会用,到懂它"的进阶之路。

希望这篇文章能陪你走好这条路。下期见!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐