第三章:Bean 工厂与对象创建

第三章:Bean 工厂与对象创建

本章将深入探讨 Jfire 的 Bean 工厂体系,理解不同工厂的设计思想和使用场景,掌握 @Bean 方法的处理机制,以及如何自定义工厂来扩展 Bean 的创建方式。

3.1 为什么需要 Bean 工厂

在第二章中,我们知道 BeanDefinition 负责管理 Bean 的生命周期,但具体的对象创建逻辑是由 Bean 工厂(BeanFactory) 来完成的。

3.1.1 对象创建的多样性

在实际开发中,创建对象的方式多种多样:

// 方式1:反射调用无参构造器
UserService service = UserService.class.getDeclaredConstructor().newInstance();

// 方式2:调用工厂方法
DataSource dataSource = DataSourceFactory.create();

// 方式3:调用配置类的 @Bean 方法
@Bean
public DataSource dataSource() {
    HikariDataSource ds = new HikariDataSource();
    ds.setUrl("jdbc:mysql://localhost:3306/test");
    return ds;
}

// 方式4:从外部获取(如 JNDI)
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/mydb");

为了支持这些不同的创建方式,Jfire 设计了 BeanFactory 接口。

3.1.2 工厂模式的优势

使用工厂模式有以下优势:

  1. 解耦BeanDefinition 不需要关心具体的创建逻辑
  2. 扩展性:新增创建方式只需实现新的工厂
  3. 封装:复杂的创建逻辑被封装在工厂内部
  4. 可替换:同一个 Bean 可以使用不同的工厂创建

3.2 BeanFactory 接口设计

让我们先看 BeanFactory 接口的定义:

// 源码:cc/jfire/jfire/core/beanfactory/BeanFactory.java

/**
 * Bean工厂接口,用于创建Bean实例
 */
public interface BeanFactory {
    /**
     * 返回该Bean定义的原始对象,也即没有经过增强、初始化等一系列操作的原始对象。
     *
     * @param beanDefinition Bean定义
     * @param <E> Bean类型
     * @return 未增强的原始Bean实例
     */
    <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition);
}

3.2.1 为什么返回"未增强"的实例?

方法名 getUnEnhanceyInstance 强调返回的是 原始对象,而非 AOP 增强后的对象。

这是因为在 Jfire 的设计中:

BeanFactory 创建原始实例
        ↓
依赖注入到原始实例
        ↓
创建增强类实例,包装原始实例
        ↓
返回增强类实例

依赖注入和 AOP 增强是在 BeanDefinition.buildInstance() 中处理的,工厂只负责最基础的对象创建。

3.2.2 BeanFactory 的实现体系

              BeanFactory (接口)
                    │
     ┌──────────────┼──────────────┐
     │              │              │
     ▼              ▼              ▼
ClassBeanFactory  MethodBeanFactory  SelectedBeanFactory
 (反射创建)       (@Bean 方法创建)    (选择性工厂)
实现类 创建方式 使用场景
ClassBeanFactory 反射调用无参构造器 @Resource 标注的普通 Bean
MethodBeanFactory 调用 @Bean 方法 @Configuration 中的 @Bean 方法
SelectedBeanFactory 委托给其他工厂 需要自定义工厂的场景

3.3 ClassBeanFactory:反射创建

ClassBeanFactory 是最常用的工厂,通过反射调用无参构造器创建对象:

// 源码:cc/jfire/jfire/core/beanfactory/impl/ClassBeanFactory.java

public class ClassBeanFactory implements BeanFactory {
    // 单例模式:全局只有一个实例
    public static final ClassBeanFactory INSTANCE = new ClassBeanFactory();

    @Override
    public <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition) {
        try {
            // 获取类型 → 获取无参构造器 → 创建实例
            return (E) beanDefinition.getType()
                .getDeclaredConstructor()
                .newInstance();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

3.3.1 源码解析

代码非常简洁,核心逻辑只有一行:

beanDefinition.getType().getDeclaredConstructor().newInstance()

让我们拆解这行代码:

步骤 方法 作用
1 beanDefinition.getType() 获取 Bean 的类型(Class 对象)
2 .getDeclaredConstructor() 获取无参构造器
3 .newInstance() 调用构造器创建实例

3.3.2 为什么使用单例模式?

public static final ClassBeanFactory INSTANCE = new ClassBeanFactory();

ClassBeanFactory 是无状态的(没有实例字段),多个实例没有意义,使用单例可以:

  1. 节省内存:避免创建多个相同的对象
  2. 提高性能:减少对象创建的开销
  3. 简化使用:直接通过 ClassBeanFactory.INSTANCE 获取

3.3.3 使用场景

当一个类被 @Resource 注解标注时,默认使用 ClassBeanFactory

// 源码:DefaultApplicationContext.java -> register() 方法

if (AnnotationContext.isAnnotationPresent(SelectBeanFactory.class, ckass)) {
    // 使用自定义工厂
    // ...
} else {
    // 默认使用 ClassBeanFactory
    return registerBeanRegisterInfo(new DefaultBeanRegisterInfo(
        prototype, ckass, beanName, this,
        ClassBeanFactory.INSTANCE  // 传入单例工厂
    ));
}

3.3.4 限制条件

使用 ClassBeanFactory 有一个前提条件:Bean 类必须有无参构造器

如果没有无参构造器,会抛出 NoSuchMethodException

@Resource
public class UserService {
    private final String name;

    // 只有带参构造器,没有无参构造器
    public UserService(String name) {
        this.name = name;
    }
}

// 运行时报错:java.lang.NoSuchMethodException

解决方案

  1. 添加无参构造器
  2. 使用 @Bean 方法创建
  3. 使用自定义工厂

3.4 MethodBeanFactory:@Bean 方法创建

MethodBeanFactory 用于处理配置类中的 @Bean 方法:

// 源码:cc/jfire/jfire/core/beanfactory/impl/MethodBeanFactory.java

public class MethodBeanFactory implements BeanFactory {
    private final ApplicationContext applicationContext;
    private final Method             method;  // @Bean 标注的方法

    public MethodBeanFactory(ApplicationContext applicationContext, Method method) {
        this.applicationContext = applicationContext;
        this.method = method;
    }

    @Override
    public <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition) {
        // 1. 获取方法所在的配置类实例
        Object hostBean = applicationContext.getBean(method.getDeclaringClass());
        if (hostBean == null) {
            throw new BeanDefinitionCanNotFindException(method.getDeclaringClass());
        }

        method.setAccessible(true);  // 允许访问私有方法
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object[]   params         = new Object[parameterTypes.length];

        try {
            if (params.length == 0) {
                // 2a. 无参方法:直接调用
                return (E) method.invoke(hostBean, null);
            } else {
                // 2b. 有参方法:从容器获取参数依赖
                for (int i = 0; i < parameterTypes.length; i++) {
                    params[i] = applicationContext.getBean(parameterTypes[i]);
                }
                return (E) method.invoke(hostBean, params);
            }
        } catch (Throwable e) {
            ReflectUtil.throwException(e);
            return null;
        }
    }
}

3.4.1 源码解析

MethodBeanFactory 的创建过程分为几个步骤:

┌─────────────────────────────────────────────────────────┐
│                  MethodBeanFactory                       │
│                                                          │
│  ┌─────────────────────────────────────────────────┐    │
│  │ 步骤1:获取配置类实例                             │    │
│  │ Object hostBean = context.getBean(declaringClass)│    │
│  └─────────────────────────┬───────────────────────┘    │
│                            │                             │
│                            ▼                             │
│  ┌─────────────────────────────────────────────────┐    │
│  │ 步骤2:获取方法参数类型                           │    │
│  │ Class<?>[] parameterTypes = method.getParameterTypes()│
│  └─────────────────────────┬───────────────────────┘    │
│                            │                             │
│                       参数数量?                          │
│                      ┌────┴────┐                        │
│                     == 0      > 0                       │
│                      │         │                        │
│                      ▼         ▼                        │
│  ┌────────────────────┐  ┌────────────────────┐        │
│  │直接调用无参方法     │  │从容器获取每个参数   │        │
│  │method.invoke(host) │  │params[i] = getBean()│        │
│  └────────────────────┘  └─────────┬──────────┘        │
│                                    │                    │
│                                    ▼                    │
│                          ┌────────────────────┐        │
│                          │调用带参方法         │        │
│                          │method.invoke(host, params)│  │
│                          └────────────────────┘        │
└─────────────────────────────────────────────────────────┘

3.4.2 参数自动注入

MethodBeanFactory 的一个重要特性是 方法参数自动注入

@Configuration
public class AppConfig {

    @Bean
    public UserService userService(UserDao userDao, OrderDao orderDao) {
        // userDao 和 orderDao 会自动从容器中获取
        return new UserService(userDao, orderDao);
    }
}

源码中的实现:

for (int i = 0; i < parameterTypes.length; i++) {
    params[i] = applicationContext.getBean(parameterTypes[i]);
}
return (E) method.invoke(hostBean, params);

3.4.3 与 ClassBeanFactory 的区别

特性 ClassBeanFactory MethodBeanFactory
创建方式 反射调用构造器 调用 @Bean 方法
无参构造器 必须 不需要
参数注入 不支持 支持方法参数注入
实例数量 单例(无状态) 每个方法一个实例
循环依赖 可以解决 无法解决
创建逻辑 简单(固定) 灵活(用户定义)

3.4.4 为什么 MethodBeanFactory 无法解决循环依赖?

回顾第二章的循环依赖检测逻辑:

if (cycData.beanFactory instanceof ClassBeanFactory) {
    index--;  // ClassBeanFactory 可以继续
} else {
    // 其他工厂类型,抛出循环依赖异常
    throw new IllegalStateException("发现循环依赖...");
}

原因分析:

  1. ClassBeanFactory:先创建空对象,再注入依赖,可以提前暴露引用
  2. MethodBeanFactory:参数必须先准备好才能调用方法,无法提前暴露
// ClassBeanFactory 的创建流程
new UserService()  // 先创建空对象(可以暴露引用)
    ↓
userService.userDao = ...  // 再注入依赖

// MethodBeanFactory 的创建流程
userService(userDao)  // 必须先有 userDao 才能调用
    ↓
// 如果 userDao 依赖 userService,死锁!

3.5 SelectedBeanFactory:选择性工厂

SelectedBeanFactory 允许用户指定使用哪个工厂来创建 Bean:

// 源码:cc/jfire/jfire/core/beanfactory/impl/SelectedBeanFactory.java

public class SelectedBeanFactory implements BeanFactory {
    private final ApplicationContext           applicationContext;
    private final String                       beanFactoryBeanName;  // 工厂的 Bean 名称
    private final Class<? extends BeanFactory> beanFactoryClass;     // 工厂的类型

    public SelectedBeanFactory(ApplicationContext applicationContext,
                               String beanFactoryBeanName,
                               Class<? extends BeanFactory> beanFactoryClass) {
        this.applicationContext = applicationContext;
        this.beanFactoryBeanName = beanFactoryBeanName;
        this.beanFactoryClass = beanFactoryClass;
    }

    @Override
    public <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition) {
        if (beanFactoryBeanName == null) {
            // 按类型获取工厂
            return applicationContext.getBean(beanFactoryClass)
                .getUnEnhanceyInstance(beanDefinition);
        } else {
            // 按名称获取工厂
            return ((BeanFactory) applicationContext.getBean(beanFactoryBeanName))
                .getUnEnhanceyInstance(beanDefinition);
        }
    }
}

3.5.1 @SelectBeanFactory 注解

使用 SelectedBeanFactory 需要在 Bean 类上标注 @SelectBeanFactory 注解:

// 源码:cc/jfire/jfire/core/beanfactory/SelectBeanFactory.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SelectBeanFactory {
    /**
     * 工厂 Bean 的名称(按名称获取)
     */
    String value() default "";

    /**
     * 工厂的类型(按类型获取)
     */
    Class<? extends BeanFactory> beanFactoryType() default BeanFactory.class;
}

3.5.2 使用示例

// 1. 定义自定义工厂
@Resource
public class MyBeanFactory implements BeanFactory {
    @Override
    public <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition) {
        // 自定义创建逻辑
        System.out.println("使用自定义工厂创建: " + beanDefinition.getBeanName());
        try {
            return (E) beanDefinition.getType().getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

// 2. 使用自定义工厂创建 Bean
@Resource
@SelectBeanFactory(beanFactoryType = MyBeanFactory.class)
public class UserService {
    // 这个 Bean 将使用 MyBeanFactory 创建
}

3.5.3 注册时的处理

DefaultApplicationContext.register() 中处理 @SelectBeanFactory

// 源码:DefaultApplicationContext.java

@Override
public RegisterResult register(Class<?> ckass) {
    // ... 省略其他逻辑

    if (AnnotationContext.isAnnotationPresent(SelectBeanFactory.class, ckass)) {
        // 有 @SelectBeanFactory 注解,使用 SelectedBeanFactory
        SelectBeanFactory selectBeanFactory =
            AnnotationContext.getAnnotation(SelectBeanFactory.class, ckass);
        return registerBeanRegisterInfo(new DefaultBeanRegisterInfo(
            prototype, ckass, beanName, this,
            new SelectedBeanFactory(
                this,
                selectBeanFactory.value().equals("") ? null : selectBeanFactory.value(),
                selectBeanFactory.beanFactoryType()
            )
        ));
    } else {
        // 默认使用 ClassBeanFactory
        return registerBeanRegisterInfo(new DefaultBeanRegisterInfo(
            prototype, ckass, beanName, this,
            ClassBeanFactory.INSTANCE
        ));
    }
}

3.6 @Bean 方法的处理机制

@Bean 注解用于在配置类中声明 Bean,让我们深入了解其处理机制。

3.6.1 @Bean 注解定义

// 源码:cc/jfire/jfire/core/prepare/annotation/configuration/Bean.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
    /**
     * bean的名称,如果不填写的话,默认为方法名
     */
    String name() default "";

    /**
     * 是否为原型模式,默认为单例
     */
    boolean prototype() default false;
}

3.6.2 ConfigurationProcessor 处理器

@Bean 方法由 ConfigurationProcessor 处理:

// 源码:cc/jfire/jfire/core/prepare/processor/ConfigurationProcessor.java

public class ConfigurationProcessor implements ContextPrepare {
    private static final Logger logger = LoggerFactory.getLogger(ConfigurationProcessor.class);

    @Override
    public ApplicationContext.FoundNewContextPrepare prepare(ApplicationContext context) {
        ErrorMessage errorMessage = new ErrorMessage();

        // 1. 收集所有配置类中的 @Bean 方法
        Set<Method> methodWithBeanAnnotation = context.getAllBeanRegisterInfos().stream()
            // 过滤出 @Configuration 类
            .filter(info -> AnnotationContext.isAnnotationPresent(
                Configuration.class, info.getType()))
            .map(info -> info.getType())
            // 获取所有声明的方法
            .flatMap(ckass -> Arrays.stream(ckass.getDeclaredMethods()))
            // 过滤出 @Bean 方法
            .filter(method -> AnnotationContext.isAnnotationPresent(Bean.class, method))
            .collect(Collectors.toSet());

        // 2. 处理没有条件注解的 @Bean 方法
        methodWithBeanAnnotation.stream()
            .filter(method -> !hasConditionalAnnotation(method))
            .forEach(method -> registerMethodBeanDefinition(method, context,
                AnnotationContext.getInstanceOn(method)));

        // 3. 处理有条件注解的 @Bean 方法(需要判断条件)
        methodWithBeanAnnotation.stream()
            .filter(method -> hasConditionalAnnotation(method))
            .filter(method -> matchAllConditions(context, method, errorMessage))
            .forEach(method -> registerMethodBeanDefinition(method, context,
                AnnotationContext.getInstanceOn(method)));

        return ApplicationContext.FoundNewContextPrepare.NO;
    }

    @Override
    public int order() {
        return PrepareConstant.CONFIGURATION_ORDER;  // 100
    }

    // ... 省略辅助方法
}

3.6.3 注册 @Bean 方法的流程

private void registerMethodBeanDefinition(Method method, ApplicationContext context,
                                         AnnotationContext annotationContextOnMethod) {
    Bean bean = annotationContextOnMethod.getAnnotation(Bean.class);

    // 1. 确定 Bean 名称:优先使用注解指定的名称,否则用方法名
    String beanName = StringUtil.isNotBlank(bean.name())
        ? bean.name()
        : method.getName();

    // 2. 创建 BeanRegisterInfo
    BeanRegisterInfo beanRegisterInfo = new DefaultBeanRegisterInfo(
        bean.prototype(),           // 是否原型
        method.getReturnType(),     // Bean 类型 = 方法返回类型
        beanName,                   // Bean 名称
        context,
        new MethodBeanFactory(context, method)  // 使用 MethodBeanFactory
    );

    // 3. 注册到容器
    context.registerBeanRegisterInfo(beanRegisterInfo);
    logger.debug("注册方法Bean:{}", method.getDeclaringClass().getSimpleName()
        + "." + method.getName());
}

3.6.4 处理流程图

                    ConfigurationProcessor.prepare()
                              │
                              ▼
              ┌───────────────────────────────┐
              │  遍历所有 BeanRegisterInfo     │
              └───────────────┬───────────────┘
                              │
                              ▼
              ┌───────────────────────────────┐
              │  过滤出 @Configuration 类      │
              └───────────────┬───────────────┘
                              │
                              ▼
              ┌───────────────────────────────┐
              │  获取类中所有 @Bean 方法        │
              └───────────────┬───────────────┘
                              │
              ┌───────────────┴───────────────┐
              │                               │
              ▼                               ▼
    ┌─────────────────┐             ┌─────────────────┐
    │ 无条件注解的方法  │             │ 有条件注解的方法  │
    │                 │             │                 │
    │ 直接注册        │             │ 判断条件是否满足  │
    └────────┬────────┘             └────────┬────────┘
             │                               │
             │                          条件满足?
             │                         ┌────┴────┐
             │                        YES       NO
             │                         │         │
             │                         ▼         ▼
             │              ┌──────────────┐  跳过注册
             │              │    注册       │
             │              └──────┬───────┘
             │                     │
             └──────────┬──────────┘
                        │
                        ▼
              ┌─────────────────────────┐
              │  创建 DefaultBeanRegisterInfo  │
              │  使用 MethodBeanFactory        │
              └─────────────────────────┘

3.7 工厂选择策略

在 Jfire 中,不同的场景使用不同的工厂:

3.7.1 工厂选择流程

                    注册 Bean
                       │
                       ▼
           ┌──────────────────────┐
           │  是 EnhanceManager?  │
           └──────────┬───────────┘
                      │
               ┌──────┴──────┐
              YES            NO
               │              │
               ▼              ▼
    直接反射创建      ┌──────────────────────┐
   (无需工厂)        │  是 ContextPrepare?  │
                    └──────────┬───────────┘
                               │
                        ┌──────┴──────┐
                       YES            NO
                        │              │
                        ▼              ▼
             直接反射创建      ┌──────────────────────┐
            (无需工厂)        │  有 @SelectBeanFactory?│
                             └──────────┬───────────┘
                                        │
                                 ┌──────┴──────┐
                                YES            NO
                                 │              │
                                 ▼              ▼
                    使用 SelectedBeanFactory   ┌──────────────────────┐
                                              │   是 @Bean 方法?     │
                                              └──────────┬───────────┘
                                                         │
                                                  ┌──────┴──────┐
                                                 YES            NO
                                                  │              │
                                                  ▼              ▼
                                    使用 MethodBeanFactory  使用 ClassBeanFactory

3.7.2 工厂使用场景总结

场景 使用的工厂 说明
@Resource 标注的普通类 ClassBeanFactory 反射调用无参构造器
@Configuration 类中的 @Bean 方法 MethodBeanFactory 调用方法创建
@SelectBeanFactory 标注的类 SelectedBeanFactory 委托给指定工厂
EnhanceManager 实现类 直接反射创建 不经过工厂
ContextPrepare 实现类 直接反射创建 不经过工厂
外部对象(如 ApplicationContext) 无需工厂 直接包装已有对象

3.8 实战:自定义 Bean 工厂

让我们通过一个实战示例,来加深对 Bean 工厂的理解。

3.8.1 场景:对象池工厂

假设我们需要实现一个对象池,每次获取 Bean 时从池中取出,而不是每次都创建新对象。

/**
 * 对象池工厂 - 从对象池中获取实例
 */
@Resource
public class PooledBeanFactory implements BeanFactory {

    // 对象池:每种类型维护一个池
    private final Map<Class<?>, Queue<Object>> pools = new ConcurrentHashMap<>();

    // 池大小
    private final int poolSize = 10;

    @Override
    public <E> E getUnEnhanceyInstance(BeanDefinition beanDefinition) {
        Class<?> type = beanDefinition.getType();
        Queue<Object> pool = pools.computeIfAbsent(type, k -> initPool(type));

        // 从池中获取
        Object instance = pool.poll();
        if (instance != null) {
            System.out.println("从对象池获取: " + type.getSimpleName());
            return (E) instance;
        }

        // 池空了,创建新实例
        System.out.println("对象池为空,创建新实例: " + type.getSimpleName());
        return createInstance(type);
    }

    /**
     * 归还对象到池中
     */
    public void returnToPool(Object instance) {
        Class<?> type = instance.getClass();
        Queue<Object> pool = pools.get(type);
        if (pool != null && pool.size() < poolSize) {
            pool.offer(instance);
            System.out.println("对象归还到池中: " + type.getSimpleName());
        }
    }

    private Queue<Object> initPool(Class<?> type) {
        Queue<Object> pool = new LinkedBlockingQueue<>(poolSize);
        // 预创建对象
        for (int i = 0; i < poolSize / 2; i++) {
            pool.offer(createInstance(type));
        }
        return pool;
    }

    private <E> E createInstance(Class<?> type) {
        try {
            return (E) type.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建实例失败: " + type.getName(), e);
        }
    }
}

3.8.2 使用对象池工厂

// 使用 @SelectBeanFactory 指定使用对象池工厂
@Resource
@SelectBeanFactory(beanFactoryType = PooledBeanFactory.class)
public class ExpensiveService {

    public void doWork() {
        System.out.println("ExpensiveService 执行工作");
    }
}

// 配置类
@Configuration
@ComponentScan("com.example")
public class AppConfig {
}

// 测试
public class PoolDemo {
    public static void main(String[] args) {
        ApplicationContext context = ApplicationContext.boot(AppConfig.class);

        // 获取服务(原型模式下每次都从池中获取)
        ExpensiveService service1 = context.getBean(ExpensiveService.class);
        service1.doWork();

        // 获取对象池工厂
        PooledBeanFactory poolFactory = context.getBean(PooledBeanFactory.class);

        // 归还对象
        poolFactory.returnToPool(service1);
    }
}

3.8.3 运行结果

从对象池获取: ExpensiveService
ExpensiveService 执行工作
对象归还到池中: ExpensiveService

3.9 工厂与 Bean 生命周期的关系

Bean 工厂在 Bean 生命周期中处于最早期的位置:

┌─────────────────────────────────────────────────────────────────┐
│                         Bean 生命周期                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────┐                                            │
│  │  BeanFactory    │ ← 工厂负责创建原始实例                      │
│  │  创建原始实例    │                                            │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐                                            │
│  │  放入临时缓存    │ ← 用于处理循环依赖                         │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐                                            │
│  │  依赖注入        │ ← InjectHandler[] 处理                    │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐                                            │
│  │  AOP 增强包装    │ ← EnhanceWrapper 包装原始实例              │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐                                            │
│  │  设置增强字段    │ ← setEnhanceFields()                       │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│  ┌─────────────────┐                                            │
│  │  初始化回调      │ ← @PostConstruct                           │
│  └────────┬────────┘                                            │
│           │                                                      │
│           ▼                                                      │
│       Bean 就绪                                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

关键点

  1. 工厂只负责创建 原始实例
  2. 依赖注入、AOP 增强、初始化回调都是在 BeanDefinition 中处理
  3. 工厂是 无状态 的(除了 MethodBeanFactory 持有方法引用)

3.10 本章小结

本章我们深入学习了 Jfire 的 Bean 工厂体系:

  1. BeanFactory 接口

    • 定义了 getUnEnhanceyInstance() 方法
    • 返回未经增强的原始实例
  2. 三种工厂实现

    • ClassBeanFactory:反射调用无参构造器,单例模式
    • MethodBeanFactory:调用 @Bean 方法,支持参数自动注入
    • SelectedBeanFactory:委托给指定的工厂
  3. @Bean 方法处理

    • ConfigurationProcessor 处理
    • 方法参数自动从容器获取
    • Bean 名称默认为方法名
  4. 工厂选择策略

    • 根据注解和类型自动选择合适的工厂
  5. 循环依赖限制

    • ClassBeanFactory 可以解决循环依赖
    • MethodBeanFactory 无法解决(参数必须先准备好)

下一章预告:我们将深入依赖注入模块,了解 Jfire 是如何实现五种不同的注入策略,以及这些策略如何协同工作来完成复杂的依赖关系管理。

思考题

  1. 为什么 ClassBeanFactory 使用单例模式,而 MethodBeanFactory 不使用?

  2. 如果一个 @Bean 方法的参数类型在容器中有多个实现,会发生什么?如何解决?

  3. 如何实现一个"懒加载工厂",在第一次获取 Bean 时才真正创建?

  4. SelectedBeanFactory 为什么需要同时支持按名称和按类型获取工厂?

核心源码清单

文件 路径 核心内容
BeanFactory.java core/beanfactory/ Bean 工厂接口
ClassBeanFactory.java core/beanfactory/impl/ 反射创建工厂
MethodBeanFactory.java core/beanfactory/impl/ @Bean 方法工厂
SelectedBeanFactory.java core/beanfactory/impl/ 选择性工厂
SelectBeanFactory.java core/beanfactory/ @SelectBeanFactory 注解
ConfigurationProcessor.java core/prepare/processor/ @Bean 方法处理器
Bean.java core/prepare/annotation/configuration/ @Bean 注解
Configuration.java core/prepare/annotation/configuration/ @Configuration 注解
Java 进阶提升,手写系列 文章被收录于专栏

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

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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