46

Spring-MVC 单例中的所有控制器是否都在不同的会话和请求之间共享?

如果是这样,我假设一个类变量像

public String name;

所有请求和会话都相同吗?所以如果用户 X 发出请求name并被设置为Paul,用户 Z 也有 Paul 作为属性?

就我而言,我不希望这种行为,但想知道是否有更简单或更清洁的 OOP 方式来拥有会话/请求变量然后session.getAttribute()/request.getAttribute()

4

2 回答 2

71

回答你的第一个问题:是的,Spring MVC 控制器默认是单例的。对象字段将永远对所有请求和所有会话共享和可见。

但是,如果没有任何同步,您可能会遇到各种并发问题(竞争条件、可见性)。因此,您的字段应该有volatileprivate顺便说一下)修饰符以避免可见性问题。

回到您的主要问题:在 Spring 中,您可以使用request-(请参阅4.5.4.2 请求范围)和会话范围(请参阅:4.5.4.3 会话范围)bean。您可以将它们注入控制器和任何其他 bean(甚至是单例!),但 Spring 确保每个请求/会话都有一个独立的实例。

将请求和会话范围的 bean 注入单例时唯一要记住的是将它们包装在范围代理中(示例取自4.5.4.5 范围 bean 作为依赖项):

<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">

    <!-- instructs the container to proxy the surrounding bean -->
    <aop:scoped-proxy/>
</bean>
于 2012-06-21T14:12:29.823 回答
13

是的,Spring-MVC 中的控制器是单例的。在多个请求之间,您的类变量会被共享,并可能导致歧义。您可以@Scope("request")在控制器上方使用注释来避免这种歧义。

于 2015-06-25T04:00:41.330 回答