第三章: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 工厂模式的优势
使用工厂模式有以下优势:
- 解耦:
BeanDefinition不需要关心具体的创建逻辑 - 扩展性:新增创建方式只需实现新的工厂
- 封装:复杂的创建逻辑被封装在工厂内部
- 可替换:同一个 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 是无状态的(没有实例字段),多个实例没有意义,使用单例可以:
- 节省内存:避免创建多个相同的对象
- 提高性能:减少对象创建的开销
- 简化使用:直接通过
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
解决方案:
- 添加无参构造器
- 使用
@Bean方法创建 - 使用自定义工厂
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("发现循环依赖...");
}
原因分析:
- ClassBeanFactory:先创建空对象,再注入依赖,可以提前暴露引用
- 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 就绪 │
│ │
└─────────────────────────────────────────────────────────────────┘
关键点:
- 工厂只负责创建 原始实例
- 依赖注入、AOP 增强、初始化回调都是在
BeanDefinition中处理 - 工厂是 无状态 的(除了
MethodBeanFactory持有方法引用)
3.10 本章小结
本章我们深入学习了 Jfire 的 Bean 工厂体系:
-
BeanFactory 接口
- 定义了
getUnEnhanceyInstance()方法 - 返回未经增强的原始实例
- 定义了
-
三种工厂实现
ClassBeanFactory:反射调用无参构造器,单例模式MethodBeanFactory:调用 @Bean 方法,支持参数自动注入SelectedBeanFactory:委托给指定的工厂
-
@Bean 方法处理
- 由
ConfigurationProcessor处理 - 方法参数自动从容器获取
- Bean 名称默认为方法名
- 由
-
工厂选择策略
- 根据注解和类型自动选择合适的工厂
-
循环依赖限制
ClassBeanFactory可以解决循环依赖MethodBeanFactory无法解决(参数必须先准备好)
下一章预告:我们将深入依赖注入模块,了解 Jfire 是如何实现五种不同的注入策略,以及这些策略如何协同工作来完成复杂的依赖关系管理。
思考题
-
为什么
ClassBeanFactory使用单例模式,而MethodBeanFactory不使用? -
如果一个 @Bean 方法的参数类型在容器中有多个实现,会发生什么?如何解决?
-
如何实现一个"懒加载工厂",在第一次获取 Bean 时才真正创建?
-
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 框架 Jfire 为蓝本,带你从零手写一个完整的 IOC 容器。专栏共 10 章,涵盖 IOC 容器核心原理:Bean 定义与生命周期、Bean 工厂设计、五种依赖注入策略、循环依赖解决方案;深入 AOP 实现:五种增强方式、字节码动态生成技术;以及企业级特性:声明式事务管理(四种传播级别)、声明式缓存框架、条件注解与自动配置机制。