【Spring】BeanFactory、FactoryBean区别和使用
BeanFactory是一个容器接口,用于对Bean的创建、管理、获取,让SpringIOC管理,负责管理所有Bean的生命周期和依赖关系,是IOC的核心实现。
ApplicationContext是对BeanFactory的扩展,包含了一些其他功能如国际化、获取配置的资源文件等。
FactoryBean是一个特殊的Bean,也是用于对Bean进行创建让SpringIOC管理,只不过Factory的创建方式支持更加复杂的创建。
1、BeanFactory、FactoryBean和ApplicationContext动态创建的Bean和使用注解(@component)注册的Bean一样都被IOC管理,可以通过注解等方法注入。
2、FactoryBean本身也是一个普通的Spring Bean,它被BeanFactory或ApplicationContext容器管理。但它同时又有特殊能力——能创建其他Bean。
3、FactoryBean创建逻辑固定,
创建单个Bean的类型;而BeanFactory是可以代码动态创建,可以注册任意类型
一、BeanFactory
BeanFactory是可以代码动态创建也可以删除Bean,可以注册任意类型,通过ApplicationContext获取。
// AiAgent动态注册客户端实例
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
// 注册Bean
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass, () -> beanInstance);
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
// 如果Bean已存在,先移除
if (beanFactory.containsBeanDefinition(beanName)) {
beanFactory.removeBeanDefinition(beanName);
}
// 注册新的Bean
beanFactory.registerBeanDefinition(beanName, beanDefinition);二、FactoryBean
FactoryBean是一个特殊的Bean接口,用于定制复杂对象的创建逻辑。当某个Bean的创建过程无法通过简单配置完成时(例如需要动态生成代理对象、连接外部资源等),可以通过实现FactoryBean接口来自定义生成逻辑。通过implements FactoryBean<目标Bean> 实现接口创建对应Bean的xxxFactoryBean来进行复杂创建逻辑
// 简单Car - 直接@Component ✅
java
@Component
public class Car {
private String brand = "BMW";
// 简单构造,无复杂逻辑
}
// 完全没问题!Spring会直接实例化
场景2:复杂Car - 需要FactoryBean ✅
java
@Component
public class CarFactoryBean implements FactoryBean<Car> {
@Value("${car.type}")
private String carType;
@Autowired
private EngineSupplier engineSupplier;
@Override
public Car getObject() {
// 复杂创建逻辑
if ("sports".equals(carType)) {
Car car = new SportsCar();
car.setEngine(engineSupplier.getHighPerformanceEngine());
car.initializeTurbo(); // 特殊初始化
return car;
} else if ("electric".equals(carType)) {
Car car = new ElectricCar();
car.setBattery(loadBatteryConfig());
car.calibrateMotors(); // 复杂校准
return car;
}
throw new IllegalArgumentException("Unknown car type");
}
}
// 无法用简单的@Component实现
获取时通过ApplicationContext ctx.getBean()获取。
public class MyFactoryBean implements FactoryBean<MyBean> {
public MyBean getObject() { return new MyBean(); }
}
// 获取方式:
ctx.getBean("CarFactoryBean"); // → Car实例
ctx.getBean("&CarFactoryBean"); // → CarFactoryBean本身三、总结
总的来说,BeanFactory是一个容器管理工具,控制了Bean的创建、获取、销毁等,提供了编程式动态注册Bean的能力;ApplicationContext是BeanFactory的扩展有更厉害的功能,而FactoryBean是一个特殊Bean,进行单个Bean的复杂逻辑创建,是声明好的。
FactoryBean能做的,BeanFactory动态注册理论上都能做,只是FactoryBean更优雅、更符合Spring的声明式风格。
| 维度 | BeanFactory | FactoryBean | ApplicationContext |
|---|---|---|---|
| 本质 | 容器接口 | 特殊Bean | 容器实现 |
| 创建方式 | 编程式动态注册 | 声明式模板 | 配置声明 + 自动扫描 |
| 灵活性 | 运行时高度灵活 | 编译时固定逻辑 | 配置灵活 |
| 使用场景 | 动态插件、运行时决策 | 复杂对象创建 | 标准Spring应用 |
| 关系 | 管理FactoryBean | 被BeanFactory管理 | 包含并扩展BeanFactory |
使用:
- 标准应用 → 直接用ApplicationContext(Spring Boot自动配置)
- 复杂对象创建 → 使用FactoryBean封装创建逻辑
- 运行时动态管理 → 通过BeanFactory编程式操作
- 简单对象 → 直接@Component或@Bean