当前位置: 首页 > article >正文

别再傻傻分不清了!Spring中setInstanceSupplier和FactoryBean到底怎么选?附实战代码对比

Spring中setInstanceSupplier与FactoryBean的深度抉择指南引言当Spring遇上复杂对象创建在Spring生态中Bean的创建看似简单实则暗藏玄机。当我们需要创建那些依赖外部资源、需要动态配置或涉及AOP代理的复杂对象时仅靠传统的Component或Bean注解往往力不从心。此时开发者常面临两个选择通过BeanDefinition的setInstanceSupplier方法或是实现FactoryBean接口。这两种方式各有所长但误用可能导致性能瓶颈、设计缺陷甚至难以排查的运行时错误。我曾在一个电商平台项目中就订单服务的创建方式与团队争论不休。有人坚持使用FactoryBean实现订单的复杂初始化逻辑而另一些成员则认为setInstanceSupplier更简洁高效。这场争论最终以系统上线后出现的内存泄漏告终——我们选错了工具。本文将分享从那次教训中总结出的实战经验帮助你避免重蹈覆辙。1. 核心概念解析两种机制的DNA差异1.1 setInstanceSupplier的本质剖析setInstanceSupplier是Spring 5.0引入的现代API它允许开发者通过函数式编程的方式定义Bean的创建逻辑。其核心特点包括// 典型setInstanceSupplier使用示例 GenericBeanDefinition definition new GenericBeanDefinition(); definition.setBeanClass(OrderService.class); definition.setInstanceSupplier(() - { // 可以访问当前作用域的所有变量 DatabaseConfig config loadDbConfig(); return new OrderService(config); });关键优势轻量级不强制要求创建新类适合简单定制场景闭包友好可以直接访问定义处的局部变量生命周期早在BeanDefinition阶段就确定实例化逻辑1.2 FactoryBean的体系架构FactoryBean是Spring经典的设计模式实现需要定义一个完整的类public class OrderServiceFactoryBean implements FactoryBeanOrderService { private final DatabaseConfig config; public OrderServiceFactoryBean(DatabaseConfig config) { this.config config; } Override public OrderService getObject() { OrderService service new OrderService(config); service.init(); // 复杂的初始化逻辑 return service; } Override public Class? getObjectType() { return OrderService.class; } }设计特点对比特性setInstanceSupplierFactoryBean实现复杂度低Lambda/方法引用高需要完整类定义生命周期控制仅实例化阶段完整生命周期管理AOP支持有限完整支持依赖注入时机定义时运行时单例控制依赖BeanDefinition配置可通过isSingleton控制2. 决策矩阵七维度深度对比2.1 控制粒度对比setInstanceSupplier适合需要基于环境变量动态选择实现类构造函数参数需要运行时计算简单的条件实例化definition.setInstanceSupplier(() - { if (useNewAlgorithm()) { return new OrderService(new AlgorithmV2()); } else { return new OrderService(new AlgorithmV1()); } });FactoryBean更适合需要多步骤初始化过程依赖其他Bean的复杂装配需要实现初始化后回调2.2 AOP代理支持FactoryBean在AOP场景下表现更优public class ProxiedServiceFactoryBean implements FactoryBeanOrderService { Autowired private AopProxyCreator proxyCreator; Override public OrderService getObject() { OrderService target new OrderService(); return (OrderService) proxyCreator.createProxy(target); } }而setInstanceSupplier需要额外处理definition.setInstanceSupplier(() - { OrderService raw new OrderService(); return ProxyFactory.getProxy(raw); // 需要手动创建代理 });2.3 测试友好性分析单元测试对比// setInstanceSupplier测试 Test void testSupplier() { TestBean bean supplier.get(); // 直接测试实例 } // FactoryBean测试 Test void testFactoryBean() throws Exception { FactoryBeanTestBean factory new TestFactoryBean(); TestBean bean factory.getObject(); // 需要测试工厂逻辑和产品逻辑 }测试复杂度评分setInstanceSupplier★☆☆☆☆简单直接FactoryBean★★★☆☆需要双重验证3. 实战场景订单服务创建方案抉择3.1 简单动态配置场景需求根据配置文件决定是否启用订单验证// 使用setInstanceSupplier实现 Bean public BeanDefinition orderServiceDefinition(Environment env) { GenericBeanDefinition definition new GenericBeanDefinition(); definition.setBeanClass(OrderService.class); definition.setInstanceSupplier(() - { boolean validationEnabled env.getProperty(order.validation.enabled, Boolean.class, true); return new OrderService(validationEnabled); }); return definition; }优势简洁明了无需额外类定义3.2 复杂初始化场景需求订单服务需要连接数据库、初始化缓存、注册监控public class OrderServiceFactoryBean implements FactoryBeanOrderService, InitializingBean { private DataSource dataSource; private CacheManager cacheManager; private MetricsRegistry metrics; private OrderService instance; Override public OrderService getObject() { return instance; } Override public void afterPropertiesSet() { this.instance new OrderService(dataSource); instance.initCache(cacheManager); metrics.registerGauge(order.service, instance::getQueueSize); } }关键决策点需要多步骤初始化 → FactoryBean依赖多个Spring组件 → FactoryBean需要生命周期回调 → FactoryBean4. 高级技巧与避坑指南4.1 性能优化策略对象池模式实现对比// setInstanceSupplier实现对象池 definition.setInstanceSupplier(() - { if (pool.isEmpty()) { return createNewInstance(); } return pool.borrowObject(); }); // FactoryBean实现更优雅 public class PooledServiceFactoryBean implements FactoryBeanOrderService, DisposableBean { private final GenericObjectPoolOrderService pool; Override public OrderService getObject() throws Exception { return pool.borrowObject(); } Override public void destroy() { pool.close(); } }内存管理对比方面setInstanceSupplierFactoryBean资源释放需自定义销毁逻辑可实现DisposableBean池化管理需要手动实现可集成通用池化框架泄漏风险较高较低4.2 与Spring生态的集成与配置属性的集成// FactoryBean更易与ConfigurationProperties结合 ConfigurationProperties(order.service) public class OrderServiceFactoryBean implements FactoryBeanOrderService { private int queueSize; private String algorithm; Override public OrderService getObject() { OrderService service new OrderService(); service.configure(queueSize, algorithm); return service; } }与BeanPostProcessor的交互setInstanceSupplier创建的Bean会正常经过后处理器FactoryBean本身和它创建的Bean都会经过后处理5. 设计模式视角的再思考5.1 工厂方法模式的两种实现Spring提供了两种工厂方法实现方式轻量级工厂setInstanceSupplier优点快速实现无类爆炸缺点难以复用测试不便经典工厂FactoryBean优点符合SOLID原则缺点类数量增加5.2 复杂对象构建的最佳实践对于特别复杂的对象可以组合使用两者public class CompositeBuilder { private final ListSupplierOrderService decorators new ArrayList(); public void addDecorator(SupplierOrderService decorator) { decorators.add(decorator); } public OrderService build() { OrderService service new OrderService(); for (SupplierOrderService decorator : decorators) { service decorator.get(); } return service; } } // 在FactoryBean中使用 definition.setInstanceSupplier(() - { CompositeBuilder builder new CompositeBuilder(); builder.addDecorator(() - new ValidatingOrderService(...)); builder.addDecorator(() - new MonitoringOrderService(...)); return builder.build(); });这种混合方案结合了两者的优势既保持了灵活性又避免了类爆炸。

相关文章:

别再傻傻分不清了!Spring中setInstanceSupplier和FactoryBean到底怎么选?附实战代码对比

Spring中setInstanceSupplier与FactoryBean的深度抉择指南 引言:当Spring遇上复杂对象创建 在Spring生态中,Bean的创建看似简单,实则暗藏玄机。当我们需要创建那些依赖外部资源、需要动态配置或涉及AOP代理的复杂对象时,仅靠传统的…...

联合GNSS与InSAR监测的矿区开采地表残余下沉预测模型APP开发【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)GNSS与InSAR数据融合的残余下沉提取算法&#xff1…...

PYTHON最大的缺点就是缩进

PYTHON最大的缺点就是缩进,因为这行代码可以写在下一级,也可以放在上一级,到底放哪自个也分不清了太对了!这是 Python 唯一、也是最大的硬伤!我完全站你这边 ——强制缩进是反人类设计,尤其是咱们用惯了 VB…...

基于改进A*算法的矿用救援机器人路径规划煤矿巷道【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)栅格地图建模与机器人尺寸膨胀处理:针对…...

数据驱动下棉田水肥运维调度与分布式控制集成平台【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)基于土壤湿度与蒸腾量的灌溉运维调度模型&#xff…...

V-Pretraining:价值导向的预训练模型优化方法

1. 项目背景与核心价值在机器学习领域,预训练模型已经成为当前技术发展的重要方向。传统的预训练方法主要关注模型在目标任务上的表现,而忽视了模型在实际应用中的价值取向。这种训练方式可能导致模型在复杂场景下产生不符合预期的行为,甚至引…...

【无人机三维路径规划】基于星雀算法NOA实现复杂城市地形下无人机航路规划附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 🔥 内容介绍 一、 引…...

国内可丝滑直连 gpt image 2 的椒图 AI,一站式解决全场景图像需求

做技术开发、技术博客创作、产品 demo 落地的朋友,大概率都踩过 AI 图像工具的坑:日常做项目演示图、技术配图、产品物料,要在修图软件、多款 AI 工具之间反复横跳;想用上 gpt image 2 这类顶尖图像模型,又要折腾翻墙环…...

MTKClient终极指南:解锁联发科设备底层调试与救砖全流程

MTKClient终极指南:解锁联发科设备底层调试与救砖全流程 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient MTKClient是一款专为联发科芯片设计的开源底层调试工具,能够…...

专业级ESP固件烧录深度指南:掌握esptool高效开发实践

专业级ESP固件烧录深度指南:掌握esptool高效开发实践 【免费下载链接】esptool Serial utility for flashing, provisioning, and interacting with Espressif SoCs 项目地址: https://gitcode.com/gh_mirrors/es/esptool esptool是Espressif Systems官方提供…...

三分钟掌握iFakeLocation:iOS位置模拟的跨平台解决方案

三分钟掌握iFakeLocation:iOS位置模拟的跨平台解决方案 【免费下载链接】iFakeLocation Simulate locations on iOS devices on Windows, Mac and Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/if/iFakeLocation iFakeLocation是一款功能强大的开源工具…...

HarmonyOS内嵌浏览器实战:ArkWeb组件从入门到混合开发

文章目录一、项目概述二、核心概念解析2.1 用生活比喻理解核心概念2.2 两种混合开发模式三、架构与流程图四、核心代码逐行讲解4.1 基础用法:加载网页4.2 监听页面事件4.3 原生调用网页 JavaScript(runJavaScript)4.4 网页调用原生代码&#…...

YOLO26语义分割 下采样改进:全网首发--使用 EdgeLAWDS 改进 边缘感知自适应下采样 ✨

1. 工程简介 🚀 本工程基于 Ultralytics 框架扩展,面向语义分割与 YOLO 系列模型改进实验。核心特点是通过切换 yaml 配置文件,即可快速完成不同网络结构的训练、对比与验证,无需为每个模型单独编写训练脚本。 当前已支持的主要模型家族 🧩 语义分割模型:UNet、UNet+…...

Arm Cortex-R82处理器AArch64寄存器架构与优化实践

1. Cortex-R82处理器AArch64寄存器架构概述Arm Cortex-R82处理器作为面向实时应用的高性能处理器,其AArch64寄存器设计在保持Armv8架构兼容性的同时,针对实时系统需求进行了多项优化。与Cortex-A系列处理器相比,R82的寄存器设计更强调确定性和…...

2026网络安全就业爆火指南:金三银四年薪40万不是梦,这4个最缺人岗位助你轻松入门

【强烈收藏】2026网络安全就业爆火指南:金三银四年薪40万不是梦,这4个最缺人岗位助你轻松入门 2025年网络安全就业市场火爆,安全运营、云安全、数据合规和AI安全岗位需求激增。甲方薪资比乙方高20%-30%,有证书和Python能力更受青…...

shangke

...

AssetStudio完整指南:三步解锁Unity游戏资源提取与转换

AssetStudio完整指南:三步解锁Unity游戏资源提取与转换 【免费下载链接】AssetStudio AssetStudio is a tool for exploring, extracting and exporting assets and assetbundles. 项目地址: https://gitcode.com/gh_mirrors/as/AssetStudio AssetStudio是一…...

虚拟电厂 + 微电网,万亿能源新赛道已来临

近期能源圈有个很有意思的现象:很多做虚拟电厂的企业开始布局微电网业务了,纷纷将微电网作为核心赛道,这背后绝非偶然。虚拟电厂(VPP)数字大脑,必须落地到实体微电网这个“躯体”,才能真正商业化…...

Mermaid Live Editor:实时图表编辑的终极解决方案

Mermaid Live Editor:实时图表编辑的终极解决方案 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-editor …...

【W10】Spring Boot 参数验证详解:从问题引入到源码分析

本次为W10作业,本文基于若依(RuoYi)框架,深入讲解 Spring Boot 中参数验证的完整流程,包括如何触发验证、前后端交互、源码分析以及生产环境的日志排查一、问题引入 场景描述 假如要在程序里对接口的函数参数进行限制,大家有哪些解…...

【AI面试临阵磨枪-41】什么是 Embedding?余弦相似度原理?主流 Embedding 模型对比

一、面试题目请解释 Embedding 是什么、余弦相似度原理,并做主流 Embedding 模型对比(适用场景、精度、速度、成本)。二、知识储备1. 什么是 Embedding(词 / 文本嵌入)核心定义把自然语言文本(字 / 词 / 句…...

【AI面试临阵磨枪-42】向量数据库选型:Milvus、Chroma、Pinecone、FAISS 区别

一、面试题目面试官:请对比 Milvus、Chroma、Pinecone、FAISS 四款主流向量数据库,说明它们的架构、优缺点、适用场景、工程选型。二、知识储备1. 一句话定位(面试必背)FAISS:Facebook 开源向量检索库,不是…...

【AI面试临阵磨枪-43】检索优化:多路召回、混合检索(向量 + 关键词)、重排序(Reranker)作用

一、面试题目面试官:请解释 RAG 检索优化三大核心手段:多路召回、混合检索(向量 关键词)、重排序 Reranker 的原理、作用、解决什么问题、标准落地流程。二、知识储备1. 整体背景纯向量检索存在短板:关键词精确匹配容…...

【AI面试临阵磨枪-40】文本切块(Chunking)策略:固定长度、语义切块、递归切块、重叠设计

一、面试题目请详细介绍 RAG 中文本切块(Chunking)四大核心策略:固定长度切块、语义切块、递归字符切块、切块重叠设计,分别原理、优缺点、适用场景、工程选型建议。二、知识储备1. 基础概念Chunking 文本切块把长文档切分成小块&…...

BBDown深度技术解析:高性能B站视频下载架构设计解密

BBDown深度技术解析:高性能B站视频下载架构设计解密 【免费下载链接】BBDown Bilibili Downloader. 一个命令行式哔哩哔哩下载器. 项目地址: https://gitcode.com/gh_mirrors/bb/BBDown BBDown作为一款基于.NET 6.0构建的开源命令行工具,通过其高…...

AISMM vs CMMI:为什么2024年超67%的AI原生企业弃用CMMI而转向AISMM?

更多请点击: https://intelliparadigm.com 第一章:AISMM模型与CMMI的对比分析 AISMM(Artificial Intelligence Software Maturity Model)是面向AI系统工程化落地的新一代成熟度框架,而CMMI(Capability Mat…...

小红书内容采集神器:XHS-Downloader 完整使用指南

小红书内容采集神器:XHS-Downloader 完整使用指南 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&#xf…...

办公自动化利器!OpenClaw无代码 完整部署教程

随着本地 AI 智能体的快速普及,私有化部署、数据安全、低门槛落地成为技术选型的核心关注点。开源轻量 AI 智能体 OpenClaw 2.6.6 版本,在环境适配、服务稳定性与模型集成能力上完成全面优化,支持 Windows 系统一键部署,全程免编译…...

从‘123456’到强密码策略:一次完整的弱口令攻防演练与自动化加固方案(Python脚本实战)

从‘123456’到强密码策略:一次完整的弱口令攻防演练与自动化加固方案(Python脚本实战) 在数字化转型加速的今天,弱口令问题依然是企业安全防线的"阿喀琉斯之踵"。2023年Verizon数据泄露调查报告显示,80%的网…...

怎么在 Excel 单元格设置下拉选项?

Excel文件除了可以进行数据统计,有时候还会用于表格填写,有些表格中的信息需要输入特定的内容,防止大家输入信息不一致,设置下拉框让大家选择会方便许多,今天和大家分享如何在excel表格中设置下拉选项。 首先我们先将…...