You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中proxyMode与scopeName底层原理及请求域Bean注入疑问

Spring request scope代理对象哈希值不变问题解答

核心原因

你在控制器中打印的numberGenerator不是真实的业务实例,是Spring生成的全局单例CGLIB代理对象,它的内存地址固定,因此System.identityHashCode的返回值永远不变。

详细机制说明

  • 你的RandomNumberGenerator配置了proxyMode = ScopedProxyMode.TARGET_CLASS,Spring会基于CGLIB生成该类的子类作为代理类。控制器是默认单例scope,初始化时只会注入一次固定的代理对象,这个代理对象在容器启动阶段就创建完成,生命周期和容器一致,不会随请求更换,因此它的identityHashCode永远相同。
  • 每次请求触发getNumber()方法调用时,代理对象不会直接执行业务逻辑,会先从当前请求的上下文里查找对应request scope的真实RandomNumberGenerator实例:如果找不到就调用构造方法创建新实例,存入request域后再转发方法调用。这就是你每次请求都会看到构造方法被调用的原因。
  • 你当前的打印逻辑输出的是外层代理对象的哈希值,而非每次新建的真实业务实例的哈希值,所以会出现构造触发但哈希不变的现象。

验证方法

你可以在RandomNumberGenerator内部打印当前真实实例的哈希值,就能看到每次请求都生成了新的实例:

public RandomNumberGenerator() {
  System.out.println("Constructor is called! 真实实例哈希:" + System.identityHashCode(this));
  number = Math.random();
}

修改后运行控制台会输出两个哈希值:一个是固定不变的代理对象哈希(控制器打印),另一个是每次请求都变化的真实实例哈希(构造方法打印)。

内容的提问来源于stack exchange,提问作者Hatef Alipoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:48:03