FactoryBean 是 Spring 中用于精细控制复杂第三方组件创建的机制,通过实现 FactoryBean<T> 接口,将初始化逻辑(如读配置、建连接池、校验环境、加代理)封装在 getObject() 中,支持懒加载、生命周期管理及 AOP 代理。

Spring 通过 FactoryBean 让你用 Java 代码完全掌控复杂第三方组件的创建过程,而不是依赖容器反射或简单@Bean方法。它不是替代@Bean,而是当初始化逻辑太重(比如要读加密配置、连远程服务、建连接池、加代理、校验环境)时的更底层、更清晰的解法。
FactoryBean 的本质:它本身是 Bean,但产出的是另一个 Bean
实现 FactoryBean<T> 的类会被 Spring 当作普通 Bean 管理(例如加 @Component),但它的作用不是被直接注入,而是作为“工厂”——
• 调用 context.getBean("myClient") → 返回的是 getObject() 创建的真实第三方实例(如 RedisTemplate、KafkaAdmin);
• 调用 context.getBean("&myClient")(名称前加 &)→ 才返回你写的 MyClientFactoryBean 实例本身(可用于调试或高级定制);
• isSingleton() 决定返回对象是否复用(默认 true);
• getObjectType() 必须准确返回目标类型,否则影响自动注入匹配(比如按类型注入会失败)。
把初始化逻辑从@Bean里搬出来,写在 getObject() 里
不要把多步校验、动态加载、重试连接、代理组装这些塞进一个@Bean方法。应该集中到 getObject() 中,并拆成可读、可测的私有方法:
- 用
loadConfig()读取并解密配置项 - 用
buildPool()初始化连接池(含最大空闲、超时等参数) - 用
validateConnection()主动连一次中间件并重试 - 用
wrapWithProxy()动态添加监控或重试切面 - 捕获具体异常(如 ConnectException、NoClassDefFoundError),包装成带上下文的 RuntimeException,避免静默失败
和 Spring 容器协同,不绕过它
FactoryBean 创建的对象依然走 Spring 生命周期管理,能被 AOP 代理、参与依赖注入、响应 @Scope。关键是要遵守规则:
- 不要在
getObject()里 new Spring Bean 并手动 set 依赖 —— 应通过构造器注入、@Autowired 或 ApplicationContext 获取已有 Bean - 如果第三方组件需要访问 Spring 上下文(比如取其他 Bean 或 Environment),让 FactoryBean 实现
ApplicationContextAware - 资源释放(如关闭连接池)不能写在
getObject()里,应在 FactoryBean 自身实现DisposableBean或定义@PreDestroy方法 - getObject() 是懒加载的:首次 getBean 时才执行,适合耗时或条件性初始化
典型场景举例
• 集成 MyBatis:SqlSessionFactoryBean 就是官方 FactoryBean,封装了 XML 解析、Mapper 扫描、DataSource 绑定;
• 构建 HTTP 客户端:Apache HttpClient 需配置 SSL、重试策略、拦截器链,全在 getObject() 里组装;
• 创建 Kafka Admin:需先验证集群连通性、动态获取 topic 列表、设置超时与权限上下文;
• 动态生成代理对象:类似 ProxyFactoryBean,根据运行时参数决定是否启用熔断或降级。


















