第二章:Bean 定义体系——容器的基石
第二章:Bean 定义体系——容器的基石
本章将深入剖析 Jfire 的 Bean 定义体系,理解
BeanDefinition和BeanRegisterInfo的设计思想,掌握单例与原型作用域的实现原理,以及循环依赖的检测与解决机制。
2.1 为什么需要 Bean 定义
在第一章中,我们知道 IOC 容器负责管理 Bean 的创建和依赖注入。但容器如何知道:
- 这个 Bean 的类型是什么?
- 应该如何创建这个 Bean?
- 这个 Bean 是单例还是原型?
- 创建后需要执行哪些初始化操作?
- 需要注入哪些依赖?
这些信息都需要通过 Bean 定义(BeanDefinition) 来描述。
2.1.1 Bean 定义的职责
Bean 定义是容器的核心数据结构,它包含了创建和管理 Bean 所需的所有元信息:
┌─────────────────────────────────────────────────────────┐
│ Bean Definition │
├─────────────────────────────────────────────────────────┤
│ - Bean 名称(beanName) │
│ - Bean 类型(type) │
│ - 作用域(singleton/prototype) │
│ - 创建方式(BeanFactory) │
│ - 依赖注入信息(InjectHandler[]) │
│ - 初始化方法(@PostConstruct) │
│ - 增强信息(EnhanceManager) │
└─────────────────────────────────────────────────────────┘
2.1.2 Jfire 的两层设计
Jfire 采用了两层设计来管理 Bean 信息:
┌──────────────────────┐
│ BeanRegisterInfo │ ← 注册信息层:管理 Bean 的注册和增强器
├──────────────────────┤
│ - beanName │
│ - type │
│ - enhanceManagers │
│ - get() → BeanDefinition
└──────────┬───────────┘
│
│ 创建
▼
┌──────────────────────┐
│ BeanDefinition │ ← 定义层:负责 Bean 的实例化
├──────────────────────┤
│ - getBean() │
│ - getBeanName() │
│ - getType() │
└──────────────────────┘
为什么需要两层?
- 职责分离:
BeanRegisterInfo负责注册阶段的信息收集,BeanDefinition负责运行时的实例创建 - 延迟创建:
BeanDefinition是在第一次需要时才从BeanRegisterInfo创建的 - 增强支持:AOP 增强信息在
BeanRegisterInfo中收集,生成BeanDefinition时统一处理
2.2 BeanDefinition 接口设计
让我们从最核心的接口开始分析:
// 源码:cc/jfire/jfire/core/bean/BeanDefinition.java
/**
* Bean定义接口,用于获取Bean实例及其元信息
*/
public interface BeanDefinition {
/**
* 获取Bean实例
* @return Bean实例
*/
Object getBean();
/**
* 获取Bean名称
* @return Bean名称
*/
String getBeanName();
/**
* 获取Bean类型
* @return Bean的Class类型
*/
Class<?> getType();
}
接口设计非常简洁,只有三个方法:
| 方法 | 职责 | 说明 |
|---|---|---|
getBean() |
获取 Bean 实例 | 核心方法,返回可用的 Bean 对象 |
getBeanName() |
获取 Bean 名称 | 用于按名称查找 Bean |
getType() |
获取 Bean 类型 | 用于按类型查找 Bean |
2.2.1 BeanDefinition 的实现体系
Jfire 提供了多个 BeanDefinition 实现,形成如下继承体系:
BeanDefinition (接口)
│
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
PrototypeBeanDefinition OutterBeanDefinition ContextPrepareBeanDefinition
│ │
│ EnhanceMangerBeanDefinition
▼
SingletonBeanDefinition
| 实现类 | 作用 | 特点 |
|---|---|---|
PrototypeBeanDefinition |
原型 Bean | 每次 getBean() 都创建新实例 |
SingletonBeanDefinition |
单例 Bean | 继承 Prototype,增加缓存 |
OutterBeanDefinition |
外部 Bean | 包装已存在的对象(如 ApplicationContext) |
ContextPrepareBeanDefinition |
准备器 Bean | 用于 ContextPrepare 实现类 |
EnhanceMangerBeanDefinition |
增强器 Bean | 用于 EnhanceManager 实现类 |
2.3 BeanRegisterInfo 接口设计
BeanRegisterInfo 是 Bean 的注册信息接口:
// 源码:cc/jfire/jfire/core/bean/BeanRegisterInfo.java
/**
* Bean注册信息接口,用于管理Bean的注册和增强
*/
public interface BeanRegisterInfo {
/**
* 获取Bean定义
* @return Bean定义实例
*/
BeanDefinition get();
/**
* 获取Bean名称
* @return Bean名称
*/
String getBeanName();
/**
* 获取Bean类型
* @return Bean的Class类型
*/
Class<?> getType();
/**
* 添加增强管理器
* @param enhanceManager 增强管理器
*/
void addEnhanceManager(EnhanceManager enhanceManager);
}
关键设计点:
get()方法:返回BeanDefinition,这是一个工厂方法addEnhanceManager():允许在容器初始化阶段收集 AOP 增强器
2.3.1 BeanDefinitionCacheHolder:缓存抽象
为了保证每个 BeanRegisterInfo 产生的 BeanDefinition 实例唯一,Jfire 设计了一个缓存抽象类:
// 源码:cc/jfire/jfire/core/bean/impl/register/BeanDefinitionCacheHolder.java
/**
* 一个BeanRegisterInfo产生的BeanDefinition实例必须是唯一的,
* 因此通过这个父类来保证唯一。
*/
public abstract class BeanDefinitionCacheHolder implements BeanRegisterInfo {
private volatile BeanDefinition cached;
@Override
public final BeanDefinition get() {
if (cached != null) {
return cached;
}
synchronized (this) {
if (cached != null) {
return cached;
} else {
cached = internalGet(); // 调用子类实现
return cached;
}
}
}
/**
* 内部获取BeanDefinition的方法,由子类实现
*/
protected abstract BeanDefinition internalGet();
}
这里使用了经典的 双检锁(Double-Check Locking) 模式:
第一次检查:cached != null?
│
YES ──→ 直接返回 cached
│
NO
│
▼
进入 synchronized 块
│
▼
第二次检查:cached != null?
│
YES ──→ 返回 cached(其他线程已创建)
│
NO
│
▼
调用 internalGet() 创建
│
▼
cached = 新创建的实例
│
▼
返回 cached
为什么需要双检锁?
- 性能:大多数情况下
cached不为 null,无需进入同步块 - 线程安全:
synchronized保证只有一个线程创建实例 - 可见性:
volatile保证cached对所有线程可见
2.4 原型 Bean 实现:PrototypeBeanDefinition
PrototypeBeanDefinition 是最基础的 Bean 定义实现,它实现了 Bean 创建的完整流程:
2.4.1 核心字段
// 源码:cc/jfire/jfire/core/bean/impl/definition/PrototypeBeanDefinition.java
public class PrototypeBeanDefinition implements BeanDefinition {
// 循环依赖检测相关
protected static final ThreadLocal<Map<String, Object>> tmpBeanInstanceMap =
ThreadLocal.withInitial(() -> new HashMap<String, Object>());
protected static final ThreadLocal<List<CycData>> cyclicDependenceQueue =
ThreadLocal.withInitial(ArrayList::new);
// Bean 创建相关
protected BeanFactory beanFactory; // Bean 工厂
protected ApplicationContext context; // 应用上下文
protected Method postConstructMethod; // @PostConstruct 方法
protected InjectHandler[] injectHandlers; // 注入处理器数组
protected Class<?> enhanceType; // AOP 增强后的类型
protected Class type; // 原始类型
protected String beanName; // Bean 名称
// 循环依赖数据记录
record CycData(String beanName, BeanFactory beanFactory) {}
}
2.4.2 构建实例的核心流程
buildInstance() 方法是整个 Bean 创建的核心:
// 源码:PrototypeBeanDefinition.java
protected synchronized Object buildInstance() {
List<CycData> cycDependStack = cyclicDependenceQueue.get();
CycData current = new CycData(beanName, beanFactory);
Map<String, Object> map = tmpBeanInstanceMap.get();
boolean cleanMark = map.isEmpty();
try {
// 步骤1:检测循环依赖
detectCyc(cycDependStack, current);
// 步骤2:检查临时缓存(处理循环依赖场景)
Object instance = map.get(getBeanName());
if (instance != null) {
return instance;
}
// 步骤3:使用 BeanFactory 创建原始实例
Object unEnhanceInstance;
unEnhanceInstance = instance = beanFactory.getUnEnhanceyInstance(this);
// 步骤4:如果需要 AOP 增强,创建增强实例
if (enhanceType != null) {
try {
EnhanceWrapper newInstance = (EnhanceWrapper) enhanceType
.getDeclaredConstructor().newInstance();
newInstance.setHost(unEnhanceInstance); // 设置原始实例
instance = newInstance;
} catch (Throwable e) {
throw new NewBeanInstanceException(e);
}
}
// 步骤5:放入临时缓存(用于循环依赖)
map.put(getBeanName(), instance);
// 步骤6:执行依赖注入
if (injectHandlers.length != 0) {
for (InjectHandler each : injectHandlers) {
each.inject(unEnhanceInstance); // 注入到原始实例
}
}
// 步骤7:设置 AOP 增强字段
if (instance instanceof EnhanceWrapper wrapper) {
wrapper.setEnhanceFields(context);
}
// 步骤8:调用 @PostConstruct 方法
if (postConstructMethod != null && beanFactory instanceof ClassBeanFactory) {
try {
postConstructMethod.invoke(instance);
} catch (Exception e) {
throw new PostConstructMethodException(e);
}
}
return instance;
} finally {
// 清理工作
if (cleanMark) {
map.clear();
}
cycDependStack.remove(cycDependStack.size() - 1);
}
}
2.4.3 构建流程图解
buildInstance()
│
▼
┌───────────────────────┐
│ 检测循环依赖 │
│ detectCyc() │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 检查临时缓存 │
│ (处理循环依赖) │
└───────────┬───────────┘
│
已缓存?
┌──┴──┐
YES NO
│ │
返回缓存 │
▼
┌───────────────────────┐
│ BeanFactory 创建 │
│ 原始实例 │
└───────────┬───────────┘
│
需要增强?
┌──┴──┐
YES NO
│ │
▼ │
┌──────────┐ │
│创建增强类 │ │
│实例 │ │
└────┬─────┘ │
│ │
└───┬───┘
│
▼
┌───────────────────────┐
│ 放入临时缓存 │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 执行依赖注入 │
│ InjectHandler[] │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 设置增强字段 │
│ setEnhanceFields() │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 调用初始化方法 │
│ @PostConstruct │
└───────────┬───────────┘
│
▼
返回实例
2.5 单例 Bean 实现:SingletonBeanDefinition
单例 Bean 是最常用的作用域,SingletonBeanDefinition 继承自 PrototypeBeanDefinition:
// 源码:cc/jfire/jfire/core/bean/impl/definition/SingletonBeanDefinition.java
public class SingletonBeanDefinition extends PrototypeBeanDefinition {
private volatile Object cachedSingletonInstance; // 单例缓存
public SingletonBeanDefinition(BeanFactory beanFactory,
ApplicationContext context,
Method postConstructMethod,
InjectHandler[] injectHandlers,
Class<?> enhanceType,
Class type,
String beanName) {
super(beanFactory, context, postConstructMethod,
injectHandlers, enhanceType, type, beanName);
}
@Override
public Object getBean() {
// 第一次检查:无锁快速路径
if (cachedSingletonInstance != null) {
return cachedSingletonInstance;
} else {
// 进入同步块
synchronized (this) {
// 第二次检查:防止重复创建
if (cachedSingletonInstance != null) {
return cachedSingletonInstance;
}
// 调用父类的 buildInstance() 创建实例
cachedSingletonInstance = buildInstance();
return cachedSingletonInstance;
}
}
}
}
2.5.1 单例与原型的对比
| 特性 | SingletonBeanDefinition | PrototypeBeanDefinition |
|---|---|---|
| 实例数量 | 整个容器中只有一个 | 每次获取都创建新的 |
| 缓存 | 有 cachedSingletonInstance |
无 |
| 线程安全 | 双检锁保证 | buildInstance() 加了 synchronized |
| 适用场景 | 无状态服务、工具类 | 有状态对象、需要隔离的场景 |
2.5.2 为什么需要 volatile?
private volatile Object cachedSingletonInstance;
volatile 关键字在这里有两个作用:
- 可见性:保证一个线程修改后,其他线程立即可见
- 禁止指令重排序:防止对象创建过程中的指令重排导致其他线程看到半初始化的对象
2.6 循环依赖检测机制
循环依赖是 IOC 容器必须处理的经典问题。看一个例子:
@Resource
public class ServiceA {
@Resource
private ServiceB serviceB; // A 依赖 B
}
@Resource
public class ServiceB {
@Resource
private ServiceA serviceA; // B 依赖 A(形成循环)
}
2.6.1 循环依赖的问题
如果不做任何处理,创建过程会陷入死循环:
创建 A → 需要注入 B → 创建 B → 需要注入 A → 创建 A → ...(无限循环)
2.6.2 Jfire 的解决方案
Jfire 使用 两个 ThreadLocal 来解决循环依赖:
// 临时实例缓存:存储正在创建中的 Bean 实例
protected static final ThreadLocal<Map<String, Object>> tmpBeanInstanceMap =
ThreadLocal.withInitial(() -> new HashMap<String, Object>());
// 依赖栈:记录当前的依赖路径,用于检测循环
protected static final ThreadLocal<List<CycData>> cyclicDependenceQueue =
ThreadLocal.withInitial(ArrayList::new);
// 循环依赖数据
record CycData(String beanName, BeanFactory beanFactory) {}
2.6.3 检测循环依赖的逻辑
// 源码:PrototypeBeanDefinition.java
private void detectCyc(List<CycData> cycDependStack, CycData current) {
if (cycDependStack.contains(current)) {
/**
* 代码运行到这一步,意味着在map中的对象发生了循环引用。
* 框架能支持的循环引用只有循环引用的Bean都是因为属性被注入,
* 且Bean的生成方式都是反射的时候才可以。
*/
int index = cycDependStack.size() - 1;
do {
CycData cycData = cycDependStack.get(index);
if (cycData.equals(current) == false) {
// 检查是否都是通过反射创建的(ClassBeanFactory)
if (cycData.beanFactory instanceof ClassBeanFactory) {
index--;
} else {
// 如果有非反射创建的 Bean,则无法解决循环依赖
int currentIndex = cycDependStack.lastIndexOf(current);
cycDependStack.add(current);
String collect = cycDependStack.stream()
.skip(currentIndex)
.map(cyc -> context.getBeanRegisterInfo(cyc.beanName)
.getType().getSimpleName())
.collect(Collectors.joining("\n↓\n"));
throw new IllegalStateException("发现循环依赖,具体为:\n" + collect);
}
} else {
cycDependStack.add(current);
break;
}
} while (index >= 0);
} else {
cycDependStack.add(current);
}
}
2.6.4 循环依赖解决流程
以 ServiceA 和 ServiceB 为例:
1. 开始创建 ServiceA
- cycDependStack: [A]
- tmpBeanInstanceMap: {}
2. 创建 A 的原始实例
- tmpBeanInstanceMap: {A: instanceA}
3. 注入 A 的依赖,发现需要 ServiceB
4. 开始创建 ServiceB
- cycDependStack: [A, B]
- tmpBeanInstanceMap: {A: instanceA}
5. 创建 B 的原始实例
- tmpBeanInstanceMap: {A: instanceA, B: instanceB}
6. 注入 B 的依赖,发现需要 ServiceA
7. 尝试创建 ServiceA
- detectCyc() 检测到 A 已在栈中
- 检查 A 和 B 都是 ClassBeanFactory 创建的
- 允许循环依赖,从 tmpBeanInstanceMap 获取 instanceA
8. B 的依赖注入完成,返回 instanceB
9. A 的依赖注入完成,返回 instanceA
2.6.5 什么情况下无法解决循环依赖?
Jfire 只能解决通过 ClassBeanFactory(反射构造器)创建的 Bean 之间的循环依赖。
无法解决的情况:
- @Bean 方法创建的 Bean:因为方法可能依赖参数,而参数在方法调用时必须已经存在
- 构造器注入:Jfire 不支持构造器注入,但如果支持,也无法解决
// 这种情况可以解决(字段注入 + 反射创建)
@Resource
public class ServiceA {
@Resource
private ServiceB serviceB;
}
// 这种情况无法解决(@Bean 方法创建)
@Configuration
public class Config {
@Bean
public ServiceA serviceA(ServiceB serviceB) { // 参数必须先存在
return new ServiceA(serviceB);
}
}
2.7 特殊 Bean 定义实现
除了普通的单例和原型 Bean,Jfire 还有几种特殊的 Bean 定义。
2.7.1 OutterBeanDefinition:外部 Bean
用于包装容器外部已经存在的对象:
// 源码:cc/jfire/jfire/core/bean/impl/definition/OutterBeanDefinition.java
public class OutterBeanDefinition implements BeanDefinition {
private final String beanName;
private final Object outter; // 外部对象
public OutterBeanDefinition(String beanName, Object outter) {
this.beanName = beanName;
this.outter = outter;
}
@Override
public Object getBean() {
return outter; // 直接返回外部对象
}
@Override
public String getBeanName() {
return beanName;
}
@Override
public Class<?> getType() {
return outter.getClass();
}
}
使用场景:
// 容器将自身注册为 Bean
registerBeanRegisterInfo(new OutterBeanRegisterInfo(this, "applicationContext"));
这样其他 Bean 就可以注入 ApplicationContext:
@Resource
public class MyService {
@Resource
private ApplicationContext applicationContext; // 可以注入
}
2.7.2 ContextPrepareBeanDefinition:准备器 Bean
用于框架内部的 ContextPrepare 实现类:
// 源码:cc/jfire/jfire/core/bean/impl/definition/ContextPrepareBeanDefinition.java
public class ContextPrepareBeanDefinition implements BeanDefinition {
private final Class<? extends ContextPrepare> type;
private final ContextPrepare contextPrepare; // 构造时就创建实例
public ContextPrepareBeanDefinition(Class<? extends ContextPrepare> type) {
if (!ContextPrepare.class.isAssignableFrom(type)) {
throw new IllegalArgumentException();
}
this.type = type;
try {
// 直接通过反射创建实例
contextPrepare = type.getDeclaredConstructor().newInstance();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@Override
public Object getBean() {
return contextPrepare;
}
// ...
}
特点:
- 构造时就创建实例(不是延迟创建)
- 不经过依赖注入、AOP 增强等流程
- 保证在容器初始化早期就可用
2.7.3 EnhanceMangerBeanDefinition:增强器 Bean
用于 EnhanceManager 实现类,结构与 ContextPrepareBeanDefinition 类似:
// 源码:cc/jfire/jfire/core/bean/impl/definition/EnhanceMangerBeanDefinition.java
public class EnhanceMangerBeanDefinition implements BeanDefinition {
private final Class<? extends EnhanceManager> type;
private final EnhanceManager enhanceManager;
public EnhanceMangerBeanDefinition(Class<? extends EnhanceManager> type) {
// 构造时直接创建实例
this.type = type;
try {
enhanceManager = type.getDeclaredConstructor().newInstance();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
// ...
}
2.8 DefaultBeanRegisterInfo:核心注册信息实现
DefaultBeanRegisterInfo 是最复杂的注册信息实现,它负责:
- 收集增强管理器
- 生成注入处理器
- 构建增强类
- 创建最终的
BeanDefinition
2.8.1 核心字段
// 源码:cc/jfire/jfire/core/bean/impl/register/DefaultBeanRegisterInfo.java
public class DefaultBeanRegisterInfo extends BeanDefinitionCacheHolder {
private final boolean prototype; // 是否原型
private final Class<?> type; // Bean 类型
private final String beanName; // Bean 名称
private final BeanFactory beanFactory; // 创建工厂
private final ApplicationContext context; // 上下文
private boolean complete = false; // 是否完成初始化
private final Set<EnhanceManager> enhanceManagers = new HashSet<>(); // 增强器集合
}
2.8.2 internalGet():创建 BeanDefinition
@Override
protected BeanDefinition internalGet() {
check(); // 确保容器初始化完成
// 1. 构建增强类(如果有增强器)
Class enhanceType = buildEnhanceType();
// 2. 生成注入处理器
InjectHandler[] injectHandlers = generateInjectHandlers();
// 3. 查找 @PostConstruct 方法
Method postConstructMethod = findPostConstructMethod();
// 4. 根据作用域创建不同的 BeanDefinition
if (prototype) {
return new PrototypeBeanDefinition(beanFactory, context,
postConstructMethod, injectHandlers, enhanceType, type, beanName);
} else {
return new SingletonBeanDefinition(beanFactory, context,
postConstructMethod, injectHandlers, enhanceType, type, beanName);
}
}
2.8.3 生成注入处理器
private InjectHandler[] generateInjectHandlers() {
if (type.isInterface()) {
return new InjectHandler[0]; // 接口没有字段
}
// 获取所有字段(包括父类)
Collection<Field> allFields = getAllFields(type);
List<InjectHandler> list = new LinkedList<>();
// 构建三种类型的注入处理器
buildCustomInjectHandlers(allFields, list); // 自定义注入
buildResourceInjectHandlers(allFields, list); // @Resource 注入
buildPropertyReadInjectHandlers(allFields, list); // @PropertyRead 注入
return list.toArray(new InjectHandler[list.size()]);
}
2.8.4 查找 @PostConstruct 方法
private Method findPostConstructMethod() {
if (type.isInterface()) {
return null;
}
Class ckass = type;
while (ckass != Object.class) {
// 查找标注了 @PostConstruct 的方法
Optional<Method> any = Arrays.stream(ckass.getDeclaredMethods())
.filter(method -> AnnotationContext.getInstanceOn(method)
.isAnnotationPresent(PostConstruct.class))
.findAny();
if (any.isPresent()) {
Method method = any.get();
// 必须是 public 方法
if (Modifier.isPublic(method.getModifiers()) == false) {
throw new IllegalStateException(
"PostConstruct标记的方法应该是public");
}
method.setAccessible(true);
return method;
} else {
ckass = ckass.getSuperclass(); // 继续查找父类
}
}
return null;
}
2.9 Bean 的完整生命周期
通过上面的源码分析,我们可以总结出 Jfire 中 Bean 的完整生命周期:
┌─────────────────────┐
│ 注册阶段 │
│ (容器初始化时) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 收集增强器 │
│ addEnhanceManager() │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 首次获取时创建 │
│ BeanDefinition │
└──────────┬──────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ 生成增强类 │ │ 生成注入器 │ │ 查找初始化 │
│ │ │ │ │ 方法 │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
▼
┌─────────────────────┐
│ getBean() 调用 │
│ (运行时) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 循环依赖检测 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ BeanFactory 创建 │
│ 原始实例 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 创建增强类实例 │
│ (如果需要) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 依赖注入 │
│ InjectHandler[] │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 设置增强字段 │
│ setEnhanceFields │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ @PostConstruct │
│ 初始化回调 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Bean 就绪可用 │
└─────────────────────┘
2.10 实战:实现一个简单的 BeanDefinition
理解了源码后,让我们动手实现一个简化版的 BeanDefinition:
/**
* 简化版 BeanDefinition 实现
*/
public class SimpleBeanDefinition {
private final String beanName;
private final Class<?> type;
private final boolean singleton;
private volatile Object singletonInstance;
public SimpleBeanDefinition(String beanName, Class<?> type, boolean singleton) {
this.beanName = beanName;
this.type = type;
this.singleton = singleton;
}
public Object getBean() {
if (singleton) {
// 单例:双检锁
if (singletonInstance == null) {
synchronized (this) {
if (singletonInstance == null) {
singletonInstance = createInstance();
}
}
}
return singletonInstance;
} else {
// 原型:每次创建新实例
return createInstance();
}
}
private Object createInstance() {
try {
// 1. 反射创建实例
Object instance = type.getDeclaredConstructor().newInstance();
// 2. 字段注入(简化版)
for (Field field : type.getDeclaredFields()) {
if (field.isAnnotationPresent(Resource.class)) {
field.setAccessible(true);
// 实际应该从容器获取依赖
// field.set(instance, container.getBean(field.getType()));
}
}
// 3. 调用初始化方法
for (Method method : type.getMethods()) {
if (method.isAnnotationPresent(PostConstruct.class)) {
method.invoke(instance);
}
}
return instance;
} catch (Exception e) {
throw new RuntimeException("创建 Bean 失败: " + beanName, e);
}
}
public String getBeanName() {
return beanName;
}
public Class<?> getType() {
return type;
}
}
2.11 本章小结
本章我们深入学习了 Jfire 的 Bean 定义体系:
-
两层设计
BeanRegisterInfo:注册阶段,收集增强器BeanDefinition:运行时,负责实例创建
-
核心实现
PrototypeBeanDefinition:原型 Bean,每次创建新实例SingletonBeanDefinition:单例 Bean,双检锁缓存实例OutterBeanDefinition:包装外部对象- 特殊 Bean:ContextPrepare、EnhanceManager
-
循环依赖
- 使用 ThreadLocal 存储临时实例和依赖栈
- 只能解决字段注入 + 反射创建的循环依赖
- @Bean 方法创建的 Bean 循环依赖会报错
-
Bean 生命周期
- 注册 → 收集增强器 → 创建 BeanDefinition → 创建实例 → 依赖注入 → 初始化回调 → 就绪
下一章预告:我们将深入 Bean 工厂模块,了解 ClassBeanFactory 和 MethodBeanFactory 是如何创建 Bean 实例的,以及 @Bean 方法的处理机制。
思考题
-
为什么
BeanDefinitionCacheHolder的get()方法要使用双检锁?如果不使用会有什么问题? -
Jfire 为什么只能解决 ClassBeanFactory 创建的 Bean 之间的循环依赖?MethodBeanFactory 为什么不行?
-
tmpBeanInstanceMap为什么使用 ThreadLocal?如果使用普通的静态 Map 会有什么问题? -
如果让你扩展一个新的作用域(如 Request 作用域),你会如何修改 Bean 定义体系?
核心源码清单
| 文件 | 路径 | 核心内容 |
|---|---|---|
| BeanDefinition.java | core/bean/ | Bean 定义接口 |
| BeanRegisterInfo.java | core/bean/ | Bean 注册信息接口 |
| PrototypeBeanDefinition.java | core/bean/impl/definition/ | 原型 Bean 实现、循环依赖检测 |
| SingletonBeanDefinition.java | core/bean/impl/definition/ | 单例 Bean 实现、双检锁 |
| OutterBeanDefinition.java | core/bean/impl/definition/ | 外部 Bean 包装 |
| ContextPrepareBeanDefinition.java | core/bean/impl/definition/ | 准备器 Bean |
| EnhanceMangerBeanDefinition.java | core/bean/impl/definition/ | 增强器 Bean |
| DefaultBeanRegisterInfo.java | core/bean/impl/register/ | 核心注册信息实现 |
| BeanDefinitionCacheHolder.java | core/bean/impl/register/ | 缓存抽象类 |
| OutterBeanRegisterInfo.java | core/bean/impl/register/ | 外部 Bean 注册信息 |
| EnhanceWrapper.java | core/aop/ | 增强包装器接口 |
专栏以轻量级 Java 框架 Jfire 为蓝本,带你从零手写一个完整的 IOC 容器。专栏共 10 章,涵盖 IOC 容器核心原理:Bean 定义与生命周期、Bean 工厂设计、五种依赖注入策略、循环依赖解决方案;深入 AOP 实现:五种增强方式、字节码动态生成技术;以及企业级特性:声明式事务管理(四种传播级别)、声明式缓存框架、条件注解与自动配置机制。