51

我正在使用超过 6 个月的弹簧。我无法理解与以下场景相关的这种底层机制。

我有一个弹簧网络应用程序。现在我在控制器中自动连接模型。根据 url 匹配它调用相应的方法。我所有的方法都是单例的。

现在,当两个用户同时打开应用程序时,spring 能够并行运行它们并为它们提供结果。我不明白它怎么能做到这一点。我的意思是,由于 bean 是单例的,它必须等待直到 bean 未被使用或覆盖 bean 中的数据。但是弹簧工作正常。有人可以用一些类比来解释这种行为。

为了清楚地解释我的问题,下面是一段代码:

我的默认控制器很简单:

@Autowired  
private AppModel aModel; 
public AppModel getModel(){
    return aModel;
}
public void setModel(AppModel aModel){
    this.aModel = aModel;
}

@RequestMapping(method = RequestMethod.GET)
public ModelAndView defaultGetter(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    ModelAndView mav = new ModelAndView(getViewName());
    mav.addObject("model", aModel);
    Runtime.getRuntime().gc();
    return mav;
}

也有人可以告诉我,当两个客户端打开应用程序时,当我使用 @autowired 时会生成两个单独的模型。如果所有客户端只存在一个模型 bean,那么说来自客户端 1 的请求进来了,我需要 30 秒才能得到结果。现在,如果第二个客户端在 3 秒内发送请求,那么第一个客户端的请求会被覆盖吗?

我想我越来越困惑了。有人可以澄清这种魔法是如何发生的吗?

谢谢

4

1 回答 1

40

每个 Web 请求都会生成一个新线程,如该线程中所述

Spring 管理不同的范围(原型、请求、会话、单例)。如果两个同时请求访问一个单例 bean,那么 bean 必须是无状态的(或至少同步以避免问题)。如果您访问范围请求中的 bean,则每个请求都会生成一个新实例。Spring 为您管理这个,但您必须小心并为您的 bean 使用正确的范围。通常,您的控制器是单例的,但AppModel必须是范围的request,否则您将遇到两个同时请求的问题。这个线程也可以帮助你

关于你的最后一个问题“这个魔法是如何发生的?”,答案是“方面/代理”。Spring 创建代理类。你可以想象 Spring 会为你的AppModel类创建一个代理。只要您尝试在控制器中访问它,Spring 就会将方法调用转发到正确的实例。

于 2013-06-21T13:21:18.070 回答