Spring 源码猎人:从一行代码看框架设计(1)
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 中,BeanDefinition 和 Bean 是两个不同的概念:
- 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 我们缺少的核心功能
-
完整的 BeanDefinition 体系
- Spring 有
BeanDefinitionReader读取不同配置源 - 支持 XML、注解、Java Config 等多种配置方式
- Spring 有
-
复杂的依赖解析
- 支持
@Qualifier按名称注入 - 支持
@Primary解决歧义 - 支持
@Resource等 JSR-250 注解
- 支持
-
三级缓存解决循环依赖
- 我们只检测到了循环依赖,但没解决
- Spring 的三级缓存可以解决 setter 注入的循环依赖
-
完整的生命周期管理
- Spring 有完整的
Aware接口体系 - 支持
@PostConstruct、@PreDestroy - 支持
InitializingBean、DisposableBean
- Spring 有完整的
-
作用域支持
- 我们只实现了 singleton 和 prototype
- Spring 还支持 request、session、application 等
-
FactoryBean 机制
- 允许通过工厂方法创建复杂的 Bean
- 我们的容器暂不支持
-
条件化配置
@Conditional及其派生注解@Profile环境切换
-
国际化支持
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→ 我们的DefaultBeanFactoryAbstractBeanFactory的doGetBean→ 我们的doGetBeanAbstractAutowireCapableBeanFactory的createBean→ 我们的createBeanAutowiredAnnotationBeanPostProcessor→ 我们的@MiniAutowired处理逻辑
9.4 下期预告
下一期,我们将深入 Spring 最难啃的骨头——循环依赖。
我们将:
- 用 Debug 的方式追踪 Spring 的三级缓存是如何工作的
- 手写代码复现循环依赖的场景
- 深入源码分析为什么三级缓存能解决 setter 注入的循环依赖,却不能解决构造器注入的循环依赖
- 探究 Spring 的设计者在面对这个经典问题时的权衡与思考
敬请期待:《Spring 源码猎人(2):三级缓存——Spring 如何解决循环依赖》
动手挑战
学完本文,建议你动手尝试:
- 扩展我们的容器:添加对
@Resource注解的支持 - 实现 FactoryBean:让容器能够处理特殊的工厂 Bean
- 尝试 Debug Spring 源码:找到
AbstractBeanFactory.doGetBean方法,跟踪一次完整的 Bean 创建过程
遇到问题时,欢迎在评论区留言交流!
写在最后
很多人问我:“为什么要手写框架?直接用不就好了吗?”
我的回答是:理解底层原理,不是为了让每个人都能写框架,而是为了在遇到问题时能快速定位,在使用时能得心应手。
当你亲手实现了 IoC 容器的核心逻辑后,再去使用 Spring:
- 你不会再对
@Autowired感到神秘 - 你不会再对 Bean 的生命周期感到困惑
- 你不会再对循环依赖的错误感到束手无策
- 你会在面试时从容地回答源码层面的问题
这就是"从会用,到懂它"的进阶之路。
希望这篇文章能陪你走好这条路。下期见!
更多推荐




所有评论(0)