首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SpringMVC @Scope会话未创建线程

SpringMVC @Scope会话未创建线程
EN

Stack Overflow用户
提问于 2013-05-13 03:01:37
回答 2查看 5.4K关注 0票数 1

假设我有下面的类。

代码语言:javascript
运行
复制
@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);
    }
}

现在,这将调用以下服务...

代码语言:javascript
运行
复制
@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:component-scan base-package="com." />,除了服务方法都作为单例运行,而不是像Java容器那样为每个会话创建一个新线程外,其他一切都运行得很好。

如果播放器被标记为静态,我可以理解。

我还尝试将我的控制器标记为@Scope("session") (如下所示),但这似乎也没有任何影响。让我的Spring应用程序为新会话创建新线程的最好方法是什么?

代码语言:javascript
运行
复制
@Controller
@Scope("session")
public class PlayerController {
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-13 03:14:07

您正在以错误的方式使用@Scope注释。

引用docs

当与组件批注一起用作类型级批注时,

指示用于带批注的类型的实例的作用域的名称。

当与Bean注释一起用作方法级注释时,表示用于从方法返回的实例的作用域的名称。

因此,如果您使用的是java config,则可以注释spring组件bean或创建bean的方法。Java配置是它编译的唯一原因(在3.0版本之前的spring中不会)

在您的例子中,注释位于普通的bean方法上,它没有任何意义。

解决正确的问题

看起来您正试图通过将查询结果存储在List<Player> players中来实现db缓存。

别干那事。取而代之的是使用一个预先构建的缓存抽象(spring有一个非常好的)。

因此, @Scope 应该去哪里?

@Scope("session")注释@Controller不会有什么帮助,因为它将创建会话作用域控制器,但它们注入的服务仍然是单例的。

只注释Service bean也不起作用,因为@Controller是一个单例,它的依赖关系在应用程序启动时自动连接。

同时注释@Service@Controller可能会起作用,但看起来有点笨拙。

最好是完全避免使用state。

票数 3
EN

Stack Overflow用户

发布于 2013-05-13 03:43:12

为每个请求创建新的线程。

您的服务有一个实例变量(播放器),它不是threadsafe -它由所有线程共享。默认情况下,任何spring bean -包括控制器和服务都是单例的,您需要在服务注释中指定其作用域。

代码语言:javascript
运行
复制
@Service("playerService")
@Scope("session")
public class PlayerServiceImpl 

但最好(更简单,更容易扩展)让bean保持单例,而不依赖于实例变量(除非它们也是由spring/threadsafe/ singletons管理的)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16510976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档