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

Spring MVC会话作用域问题:多HTTP会话共享列表异常求助

排查与解决Spring MVC会话作用域Bean共享问题

嘿,我之前也踩过这个坑!你的思路完全没问题——用session作用域实现会话间数据隔离、会话内控制器共享,但问题出在Spring没有正确为会话作用域Bean创建代理,导致它被当成单例Bean处理了,所以所有请求共用同一个实例。

问题根源

默认情况下,当你给@Component标注的类设置@Scope("session")时,如果不指定代理模式,Spring不会为它生成代理对象。而你的SessionController默认是单例的(即使加了@Scope("request")也没必要,控制器单例完全安全),单例控制器注入的Bean会被缓存,导致所有会话都拿到同一个MySession实例,自然列表就共享了。

修改方案

只需要两步就能解决:

1. 给MySession添加代理模式配置

修改MySession类,指定proxyMode = ScopedProxyMode.TARGET_CLASS,让Spring为会话作用域Bean生成CGLIB代理,这样每次调用都会获取当前会话的实例:

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MySession {
    // 建议初始化列表,避免空指针异常
    public List<String> mylist = new ArrayList<>();
}

2. 优化控制器的作用域配置

控制器不需要设置@Scope("request"),Spring MVC的控制器默认是单例的,而且单例控制器注入代理后的会话Bean完全安全,去掉这个多余配置:

@Controller
public class SessionController {

    @Autowired
    private MySession mySession;

    @RequestMapping("/updateSession")
    public ModelAndView updateSession(@RequestParam("id") int id) {
        // 示例操作:添加元素到当前会话的列表
        mySession.mylist.add("操作ID: " + id);
        // 其他增删操作...
        return new ModelAndView("result");
    }
}

验证方法

  • 用不同的浏览器(或同一个浏览器的隐私模式)发起请求,每个浏览器代表一个独立的HTTP会话,此时各自的列表应该是独立的。
  • 同一个浏览器内多次请求,列表会持续更新,而其他浏览器的列表不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:56:44