Reputation: 66216
Assume that we have Spring bean UserController with singleton
scope.
All my further reasoning is based on my assumption that "singleton" scope is almost similar to application scope i.e. we have only one instance for all users. If this is wrong assumption then tell me about it, please.
So, we have a web-form with several fields. Two users fill this form simultaneously. And they both press Submit button at the same time. Our UserController is a backing bean for that form.
My question: is it possible that part of the fields in UserController will contain values from first user, and the rest of the fields will contain values from the second user?
Upvotes: 2
Views: 3352
Reputation: 1109532
In MVC paradigm you can perfectly have a controller in the application scope (such as a Servlet
already by default is), the representative class only should not contain fields which are associated with request scoped variables. You should declare them in the method block.
Thus not for example
public class Controller {
private SomeObject field; // Not threadsafe as this will be shared among all requests!
public void control(Request request, Response response) {
this.field = request.getSomething();
}
}
but more so
public class Controller {
public void control(Request request, Response response) {
SomeObject field = request.getSomething(); // Threadsafe.
}
}
The View
and the associated Action
should be handled threadlocal, i.e. declared in the method block. E.g.
public class Controller {
public void control(Request request, Response response) {
View view = new View(request, response);
Action action = ActionFactory.getAction(request);
action.execute(view);
view.navigate();
}
}
The Model
is to be handled in the Action
class, also in the threadlocal scope.
public class SomeAction implements Action {
public void execute(View view) {
Model model = new Model();
// ...
}
}
In the JSF context you in fact only have the Model
class which is in essence nothing more than a backing bean. The Controller
and View
parts are already handled by JSF with help of FacesServlet
controlling the request/response/lifecycle/actions and the UIViewRoot
which is built up from JSF pages. Thus, for request scoped data your JSF bean should be request scoped.
Upvotes: 4
Reputation: 23229
You shouldn't be using a singleton/application scoped bean to handle per-request/user inputs.
You probably want a request scoped bean that you can bind the form parameters to, and then maybe inject the singleton bean into that request bean if you need something in the singleton bean (say something like a EntityManager).
Upvotes: 0
Reputation: 597362
You are right that singleton
= application
. Spring's WebApplicationContext
is stored in the ServletContext
, so it's one per application.
Your controllers shoud not be of singleton
scope. They should be either request
or session
scoped. Your service layer should consist of singleton
s
If your controller is singleton
it is pretty certain that the whole thing will be messed up ;)
Upvotes: 2