Spring-Controller 的作用域及其实例变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11139571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scope of a Spring-Controller and its instance-variables
提问by Gundon
Are all controllers in Spring-MVC singletons and are shared among different sessions and requests?
Spring-MVC 中的所有控制器是否都是单例并在不同的会话和请求之间共享?
If so, I assume that a class-variable like
如果是这样,我假设一个类变量像
public String name;
would be the same for all requests and sessions? So that if User X makes a request and nameis being set to Paul, User Z also has Paul as attribute?
所有请求和会话都一样吗?那么如果用户 X 发出请求name并被设置为Paul,那么用户 Z 也将 Paul 作为属性?
In my case I do NOT want that behaviour but wondered if there is a more easier, or more cleaner OOP-way to have session/request-variables then session.getAttribute()/request.getAttribute()
在我的情况下,我不想要这种行为,但想知道是否有更简单或更干净的 OOP 方式来拥有会话/请求变量session.getAttribute()/request.getAttribute()
回答by Tomasz Nurkiewicz
To answer your first question: yes, Spring MVC controllers are singletons by default. An object field will be shared and visible for all requests and all sessions forever.
回答你的第一个问题:是的,Spring MVC 控制器默认是单例的。对象字段将永远共享和可见于所有请求和所有会话。
However without any synchronization you might run into all sorts of concurrency issues (race conditions, visibility). Thus your field should have volatile(and private, by the way) modifier to avoid visibility issues.
但是,如果没有任何同步,您可能会遇到各种并发问题(竞争条件、可见性)。因此,您的字段应该具有volatile(并且private顺便说一下)修饰符以避免可见性问题。
Back to your main question: in Spring you can use request-(see 4.5.4.2 Request scope) and session-scoped(see: 4.5.4.3 Session scope) beans. You can inject them to controllers and any other beans (even singletons!), but Spring makes sure each request/session has an independent instance.
回到您的主要问题:在 Spring 中,您可以使用request-(请参阅4.5.4.2 请求范围)和会话范围(请参阅:4.5.4.3 会话范围)bean。您可以将它们注入控制器和任何其他 bean(甚至是单例!),但 Spring 确保每个请求/会话都有一个独立的实例。
Only thing to remember when injecting request- and session-scoped beans into singletons is to wrap them in scoped proxy (example taken from 4.5.4.5 Scoped beans as dependencies):
将请求范围和会话范围的 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>
回答by Ankit Pandoh
Yes, controllers in Spring-MVC are singletons. Between multiple requests your class variable get shared and might result into ambiguity. You can use @Scope("request") annotation above your controller to avoid such ambiguity.
是的,Spring-MVC 中的控制器是单例的。在多个请求之间,您的类变量被共享并可能导致歧义。您可以在控制器上方使用 @Scope("request") 注释来避免这种歧义。

