Spring-MVC单例中的所有控制器是否都在不同的会话和请求之间共享?
如果是这样,我假设一个类变量,如
public String name;
所有请求和会话的都是一样的吗?因此,如果用户X发出请求并且name
被设置为 Paul ,则用户Z还将Paul作为属性?
在我的情况下,我不希望这种行为,但想知道是否有更简单,更清晰的OOP方式来获得会话/请求变量session.getAttribute()
/ request.getAttribute()
答案 0 :(得分:59)
回答你的第一个问题:是的,Spring MVC控制器默认是单例。对于所有请求和所有会话,将永久共享和显示对象字段。
但是,如果没有任何同步,您可能会遇到各种并发问题(竞争条件,可见性)。因此,您的字段应该volatile
(并且private
,顺便说一下)修饰符,以避免可见性问题。
回到你的主要问题:在Spring中你可以使用 request - (参见4.5.4.2 Request scope)和 session-scoped (参见:4.5.4.3 Session scope ) 豆子。你可以将它们注入控制器和任何其他bean(甚至是单例!),但是Spring确保每个请求/会话都有一个独立的实例。
将请求和会话范围的bean注入单例时要记住的唯一事情是将它们包装在作用域代理中(例如取自4.5.4.5 Scoped beans as dependencies):
<!-- 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>
答案 1 :(得分:8)
是的,Spring-MVC中的控制器是单例。在多个请求之间,您的类变量会被共享,并可能导致歧义。 您可以在控制器上方使用@Scope(“request”)注释来避免这种歧义。