Spring-MVC 单例中的所有控制器是否都在不同的会话和请求之间共享?
如果是这样,我假设一个类变量像
public String name;
所有请求和会话都相同吗?所以如果用户 X 发出请求name
并被设置为Paul,用户 Z 也有 Paul 作为属性?
就我而言,我不希望这种行为,但想知道是否有更简单或更清洁的 OOP 方式来拥有会话/请求变量然后session.getAttribute()
/request.getAttribute()
Spring-MVC 单例中的所有控制器是否都在不同的会话和请求之间共享?
如果是这样,我假设一个类变量像
public String name;
所有请求和会话都相同吗?所以如果用户 X 发出请求name
并被设置为Paul,用户 Z 也有 Paul 作为属性?
就我而言,我不希望这种行为,但想知道是否有更简单或更清洁的 OOP 方式来拥有会话/请求变量然后session.getAttribute()
/request.getAttribute()
回答你的第一个问题:是的,Spring MVC 控制器默认是单例的。对象字段将永远对所有请求和所有会话共享和可见。
但是,如果没有任何同步,您可能会遇到各种并发问题(竞争条件、可见性)。因此,您的字段应该有volatile
(private
顺便说一下)修饰符以避免可见性问题。
回到您的主要问题:在 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>
是的,Spring-MVC 中的控制器是单例的。在多个请求之间,您的类变量会被共享,并可能导致歧义。您可以@Scope("request")
在控制器上方使用注释来避免这种歧义。