Spring 中的 ObjectFactory 是什么?
- 标签:后端、Spring
🏛 业务架构师
ObjectFactory 是一个函数式接口,只有一个 getObject() 方法,作用是按需、延迟地获取一个 Bean。它和 @Lazy、三级缓存关系密切:容器注入的不是目标对象本身,而是一个"取件的凭证",第一次真正使用时才触发获取。
业务上它解决三类问题:
- 打破循环依赖:A、B 互相依赖时,给一方注入
ObjectProvider<B>(ObjectFactory 的增强版),用到时再取,把启动期的环变成运行期的延迟解析; - 可选依赖:容器里可能没有这个 Bean 时,
ObjectProvider可以getIfAvailable()优雅降级,避免启动失败——做可选组件(如未部署的分析服务)集成时很有用; - 延迟初始化昂贵资源:低频使用的重依赖不必启动时就绪,缩短启动时间,这对弹性扩容场景(K8s 快速拉起 Pod)有实际价值。
三者的层次我也习惯一句话讲清:BeanFactory 是大仓库,FactoryBean 是专用机床,ObjectFactory 是取件凭证。
2026 年的实战建议:优先用 ObjectProvider(支持 Stream、Supplier 和默认值),它出现在构造器参数里时 Spring 会自动注入,不需要注解。但同样地,不要为延迟而延迟——只有依赖确实昂贵、可选或有环时才值得引入这层间接。
🏗 系统架构师
ObjectFactory 是「按需获取单个对象」的函数式接口(getObject()),ObjectProvider 是它在容器场景的增强版,提供 ifAvailable、stream、orderedStream 等能力。
我理解的三个架构用途:
- 打破循环依赖:A 不直接持有 B,而是持有
ObjectFactory<B>,首次使用时才向容器索要,把构造期环转化为运行期延迟解析; - 可选依赖与优雅降级:插件化架构里某个增强组件可能不存在,用
ifAvailable优雅降级,而不是required=false的注入散落各处; - 框架内部大量使用:三级缓存里存的就是 ObjectFactory;注入
ObjectProvider<T>还能解决「集合注入目标为空时抛异常」的问题——stream 拿空集合即可。
一句话区分:FactoryBean 是「造对象的方式复杂」,ObjectFactory 是「拿对象的时机延后」。两者经常被混为一谈,面试主动分开讲是加分点。
💻 全栈开发专家
ObjectFactory 是个函数式接口,只有一个 getObject(),语义是延迟、按需获取一个 Bean:
java
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}两个高频出场位置:
- 三级缓存:
singletonFactories存的就是它,被循环依赖引用时才回调getEarlyBeanReference()决定给原始对象还是代理——"工厂"就是为延迟决策而生 - 解决单例注入 prototype 失效:单例 A 注入 prototype B 时,A 只初始化一次,B 也只造一次,之后永远用同一个实例。正确姿势是每次取新实例:
java
@Autowired
private ObjectProvider<TaskContext> taskProvider;
public void handle() {
taskProvider.getObject().run();
}实际项目我更常用它的子接口 ObjectProvider——多了 getIfAvailable()(没有不报错)、getIfUnique()、stream()/orderedStream(),配合 @Order 把某类全部实现排着序拿,做插件化扩展非常顺手。
区分记忆:FactoryBean 是"生产 Bean 的 Bean"(容器级扩展);ObjectFactory 是"取 Bean 的回调"(注入级延迟)。