Spring Boot中RequestScope仓库Autowire未为新请求创建实例
问题分析与解决方案
核心误区:打印的是代理对象的哈希值
你看到的同一个hashCode,本质是Spring为request-scoped bean创建的代理对象是单例的,而非实际的Repository实例复用。这个代理会在每个请求上下文里动态获取真正的request-scoped Repository实例,但代理本身的哈希值不会变,导致你误以为实例没更新。
正确验证方式
要确认实际实例是否为请求级别的,需要获取代理背后的真实对象再打印哈希值。可以用Spring的AopTestUtils工具类(需引入spring-test依赖):
修改服务类中的打印代码:
import org.springframework.test.util.AopTestUtils; // ... 其他代码 @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void createMasterTableEntry(String jsonData, String mandantId, String dataIdentifier) { // 获取真实的request-scoped实例 MasterRepository realRepo = AopTestUtils.getTargetObject(masterRepository); loggers.info(">>> 真实实例hashCode: " + realRepo.hashCode()); loggers.info(">>> 代理对象hashCode: " + masterRepository.hashCode()); }
此时你会发现,代理对象的hashCode始终不变,但真实实例的hashCode会随每个请求变化。
针对你尝试的方案的修正
1. @Scope配置的补充
你的Repository上的@Scope配置是正确的,由于MasterRepository是接口,也可以将proxyMode设置为ScopedProxyMode.INTERFACES,效果一致。
2. ObjectFactory/Provider的正确用法
如果你用ObjectFactory或Provider注入,需要每次请求时调用get()方法获取新实例,而不是直接打印工厂/提供者本身的hashCode:
@Autowired private transient ObjectFactory<MasterRepository> repoFactory; // 或者用Provider // @Autowired // private transient Provider<MasterRepository> repoProvider; @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void createMasterTableEntry(String jsonData, String mandantId, String dataIdentifier) { MasterRepository repo = repoFactory.getObject(); // MasterRepository repo = repoProvider.get(); loggers.info(">>> 实例hashCode: " + repo.hashCode()); }
这样每次调用get()都会返回当前请求上下文的新实例。
额外检查点
- 确保你的请求确实是不同的HTTP请求(比如用Postman多次发送、不同浏览器窗口请求),而非同一个请求内的多次方法调用。
- 确认Spring Boot的自动配置没有覆盖你的scope设置,避免额外的Repository代理配置冲突。
内容的提问来源于stack exchange,提问作者mariya cherian
相关产品推荐
相关产品推荐

