Scope of a Spring-Controller and its instance-vari

2019-01-08 06:03发布

问题:

Are all controllers in Spring-MVC singletons and are shared among different sessions and requests?

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 name is being set to Paul, User Z also has Paul as attribute?

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()

回答1:

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.

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.

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.

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):

<!-- 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>


回答2:

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.