【发布时间】:2013-05-06 19:59:45
【问题描述】:
假设我有以下课程......
@Controller
public class WebController {
@Autowired PersonService personService;
@RequestMapping(value = "/get", method = RequestMethod.GET)
@ResponseBody
@Scope("session")
public List<Player> getPerson(String personName) {
return playerService.getByName(personName);
}
}
现在这会调用以下服务...
@Service("playerService")
public class PlayerServiceImpl implements PlayerService {
private List<Player> players;
@Override
@Transactional
public List<Player> getByName(final String name) {
if (players == null) {
players = getAll();
}
return getValidPlayers(name);
}
如果我最初启动我的应用程序,players 正确地为空,然后在同一个会话中,我再次使用新值调用此方法,players 不再为空,正如您所期望的那样。但是,似乎没有创建新线程,如果我打开一个新的浏览器窗口(因此创建一个新会话)并调用此方法,它仍然具有上一个会话的值。
为什么@Scope("session") 没有在线程池中创建新线程?
我已经按预期在我的 servlet-context 中指定了 <context:component-scan base-package="com." />,除了服务方法都充当单例而不是像 Java EE 容器那样为每个会话创建一个新线程之外,一切正常。
如果玩家被标记为静态,我会理解。
我也尝试将我的控制器标记为@Scope("session")(如下所示),但这似乎也没有影响。让我的 Spring 应用为新会话创建新线程的最佳方法是什么?
@Controller
@Scope("session")
public class PlayerController {
【问题讨论】:
-
除了灵魂检查的回答之外,您还有几点错误。会话不等同于线程(在同步 servlet 容器中,线程为请求提供服务,但同一会话的请求可能由不同的线程提供服务;无论应用程序是有状态还是无状态,都使用线程)。而一个新的浏览器窗口只会在隐身模式下创建一个新会话,否则 cookie 是共享的,您显然会获得相同的会话。
-
@NimChimpsky 哈哈,现在我才查看该链接。本可以为我节省一些打字时间:)
-
@FrankPavageau 对不起,我应该说,当我在不同的浏览器中打开一个新的浏览器窗口时,比如在 IE 中打开一个新的浏览器窗口,在 Chrome 中打开一个,会话不共享。