Spring-Controller的范围及其实例变量

Gun*_*don 43 spring spring-mvc

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

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

public String name;
Run Code Online (Sandbox Code Playgroud)

对于所有请求和会话都是一样的吗?因此,如果用户X发出请求并且name正在设置为Paul,则用户Z还将Paul作为属性?

在我的情况下,我不希望这种行为,但想知道是否有一个更简单,或更清洁的OOP方式,以获得会话/请求变量然后session.getAttribute()/request.getAttribute()

Tom*_*icz 62

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

但是,如果没有任何同步,您可能会遇到各种并发问题(竞争条件,可见性).因此,您的字段应具有volatile(并且private顺便)修饰符以避免可见性问题.

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

将请求和会话范围的bean注入单例时要记住的唯一事情就是将它们包装在作用域代理中(例如从4.5.4.5作为依赖关系的Scoped 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>
Run Code Online (Sandbox Code Playgroud)

  • 从 /sf/ask/315252451/,使用 @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 使用注释配置 aop:scoped-proxy。 (2认同)

Ank*_*doh 10

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