第二章:Bean 定义体系——容器的基石

第二章:Bean 定义体系——容器的基石

本章将深入剖析 Jfire 的 Bean 定义体系,理解 BeanDefinitionBeanRegisterInfo 的设计思想,掌握单例与原型作用域的实现原理,以及循环依赖的检测与解决机制。

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()        │
└──────────────────────┘

为什么需要两层?

  1. 职责分离BeanRegisterInfo 负责注册阶段的信息收集,BeanDefinition 负责运行时的实例创建
  2. 延迟创建BeanDefinition 是在第一次需要时才从 BeanRegisterInfo 创建的
  3. 增强支持: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);
}

关键设计点:

  1. get() 方法:返回 BeanDefinition,这是一个工厂方法
  2. 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

为什么需要双检锁?

  1. 性能:大多数情况下 cached 不为 null,无需进入同步块
  2. 线程安全synchronized 保证只有一个线程创建实例
  3. 可见性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 关键字在这里有两个作用:

  1. 可见性:保证一个线程修改后,其他线程立即可见
  2. 禁止指令重排序:防止对象创建过程中的指令重排导致其他线程看到半初始化的对象

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 之间的循环依赖。

无法解决的情况

  1. @Bean 方法创建的 Bean:因为方法可能依赖参数,而参数在方法调用时必须已经存在
  2. 构造器注入: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;
    }
    // ...
}

特点

  1. 构造时就创建实例(不是延迟创建)
  2. 不经过依赖注入、AOP 增强等流程
  3. 保证在容器初始化早期就可用

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 是最复杂的注册信息实现,它负责:

  1. 收集增强管理器
  2. 生成注入处理器
  3. 构建增强类
  4. 创建最终的 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 定义体系:

  1. 两层设计

    • BeanRegisterInfo:注册阶段,收集增强器
    • BeanDefinition:运行时,负责实例创建
  2. 核心实现

    • PrototypeBeanDefinition:原型 Bean,每次创建新实例
    • SingletonBeanDefinition:单例 Bean,双检锁缓存实例
    • OutterBeanDefinition:包装外部对象
    • 特殊 Bean:ContextPrepare、EnhanceManager
  3. 循环依赖

    • 使用 ThreadLocal 存储临时实例和依赖栈
    • 只能解决字段注入 + 反射创建的循环依赖
    • @Bean 方法创建的 Bean 循环依赖会报错
  4. Bean 生命周期

    • 注册 → 收集增强器 → 创建 BeanDefinition → 创建实例 → 依赖注入 → 初始化回调 → 就绪

下一章预告:我们将深入 Bean 工厂模块,了解 ClassBeanFactoryMethodBeanFactory 是如何创建 Bean 实例的,以及 @Bean 方法的处理机制。

思考题

  1. 为什么 BeanDefinitionCacheHolderget() 方法要使用双检锁?如果不使用会有什么问题?

  2. Jfire 为什么只能解决 ClassBeanFactory 创建的 Bean 之间的循环依赖?MethodBeanFactory 为什么不行?

  3. tmpBeanInstanceMap 为什么使用 ThreadLocal?如果使用普通的静态 Map 会有什么问题?

  4. 如果让你扩展一个新的作用域(如 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 进阶提升,手写系列 文章被收录于专栏

专栏以轻量级 Java 框架 Jfire 为蓝本,带你从零手写一个完整的 IOC 容器。专栏共 10 章,涵盖 IOC 容器核心原理:Bean 定义与生命周期、Bean 工厂设计、五种依赖注入策略、循环依赖解决方案;深入 AOP 实现:五种增强方式、字节码动态生成技术;以及企业级特性:声明式事务管理(四种传播级别)、声明式缓存框架、条件注解与自动配置机制。

全部评论

相关推荐

11-26 04:10
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务