多例(prototype)Bean

一、多例(prototype)Bean 的创建时机

多例 Bean 不存在"预初始化"行为,其创建时机严格遵循"按需创建"原则,即每次通过 Spring 容器获取 Bean 时才会创建新的实例,具体触发场景包括:

  • 主动获取:通过 Spring 上下文(ApplicationContext)的 context.getBean(BeanClass.class)context.getBean("beanName") 方法主动获取时,创建新实例;

  • 依赖注入:当其他 Bean(单例或多例)依赖该多例 Bean 时,注入过程中会创建新实例(注:单例 Bean 依赖多例 Bean 时存在特殊问题,详见下文)。

测试场景价值:该特性确保每个测试用例获取的多例 Bean 都是全新的、无历史状态的实例,避免前一个测试用例的操作影响后一个测试用例的结果(如测试用例1修改了 Bean 的成员变量,测试用例2获取新实例可避免受该修改影响)。

二、多例(prototype)Bean 的生命周期特点

与单例 Bean 不同,多例 Bean 的生命周期管理具有"不完整"特性,Spring 仅负责前两个阶段,后续阶段由调用者和 GC 主导:

  1. Spring 负责阶段:Bean 的创建(实例化)和初始化(如执行 @PostConstruct 注解方法、实现 InitializingBean 接口的 afterPropertiesSet() 方法);

  2. Spring 不负责阶段:Bean 的销毁。多例 Bean 实例创建后,其生命周期控制权完全交给调用者,Spring 不会跟踪实例的引用状态,也不会主动触发销毁方法(如 @PreDestroy 注解方法、实现 DisposableBean 接口的 destroy() 方法);

  3. 最终回收:当多例 Bean 实例不再被任何对象引用时,由 JVM 的垃圾回收器(GC)自动回收,释放内存资源。

测试场景注意:若多例 Bean 持有资源(如数据库连接、文件流),测试完成后需手动调用自定义的资源释放方法,避免资源泄露影响测试环境稳定性。

三、测试场景核心注意:依赖注入的特殊规则

测试场景中,多例 Bean 与单例 Bean 的依赖注入存在明确的规则差异,若误用会导致测试结果异常,需重点关注

1. 多例 Bean 中注入单例 Bean:允许且正常生效

多例 Bean 中注入单例 Bean 是完全合法的,且符合预期:单例 Bean 由 Spring 容器全局管理,仅存在一个实例,该实例会被所有多例 Bean 共享。

测试场景示例:多个测试用例对应的多例测试 Bean 注入同一个单例的数据源 Bean,确保所有测试用例使用相同的数据源连接,保障测试环境的一致性。

2. 单例 Bean 中注入多例 Bean:存在失效问题,需特殊处理

这是测试场景中最易踩坑的点:单例 Bean 仅在容器启动时初始化一次,初始化过程中会注入依赖的多例 Bean------此时注入的是第一次创建的多例 Bean 实例,后续单例 Bean 复用过程中,不会再次创建新的多例实例,导致多例 Bean 失去"每次获取均为新实例"的特性,即"多例失效"。

测试场景影响:若测试用例依赖的单例 Bean 内部持有多例 Bean,多个测试用例会共享同一个多例 Bean 实例,出现测试用例间的状态干扰,导致测试结果不准确。

解决方案:在单例 Bean 中通过 Spring 上下文(ApplicationContext)动态获取多例 Bean,而非直接依赖注入。具体实现方式:

  • 让单例 Bean 实现 ApplicationContextAware 接口,通过重写 setApplicationContext(ApplicationContext context) 方法获取上下文;

  • 每次需要使用多例 Bean 时,通过context.getBean(PrototypeBean.class) 动态获取,确保每次获取的都是新实例。

测试场景使用建议

  1. 优先用于状态化测试组件:如测试用例的参数载体、测试数据上下文等,确保每个测试用例的状态独立;

  2. 避免多例 Bean 持有持久化资源:若必须持有,需在测试用例的 @After方法中手动释放资源;

  3. 单例依赖多例时强制动态获取:在测试代码或被测试的单例 Bean 中,通过 ApplicationContext 动态获取多例 Bean,规避多例失效问题;

  4. 结合测试框架注解:在 Spring Boot 测试中,可通过 @SpringBootTest 加载上下文后,在每个测试用例中通过 @Autowired 结合动态获取的方式使用多例 Bean,保障测试灵活性。

相关推荐
想吃火锅10053 天前
【前端手撕】instanceof
前端·javascript·原型模式
UXbot3 天前
帮助企业低门槛开展AI应用开发的平台推荐
前端·低代码·ui·交互·产品经理·原型模式·web app
UXbot4 天前
如何选择适合公司项目的UI设计工具?企业选型指南
前端·低代码·ui·团队开发·原型模式·设计规范·web app
UXbot4 天前
原型设计工具如何帮助新人快速进入产品行业?
前端·低代码·ui·交互·团队开发·原型模式·web app
sunny.day8 天前
js原型与原型链
开发语言·javascript·原型模式·js原型链
UXbot9 天前
AI网页开发工具能替代工具吗?5大平台对比
前端·人工智能·低代码·ui·原型模式·web app
weixin_307779139 天前
从“大海捞针”到“主动推理”:AI如何重塑云原生故障诊断的根因链
开发语言·人工智能·算法·自动化·原型模式
swordbob10 天前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
isNotNullX10 天前
企业数据中台建设,ETL工具选错了会踩哪些坑?
数据仓库·etl·原型模式
半个烧饼不加肉10 天前
JS 底层探究-- 普通函数和构造函数
开发语言·javascript·原型模式