views:

148

answers:

3

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?

+1  A: 
  1. You are right that singleton = application. Spring's WebApplicationContext is stored in the ServletContext, so it's one per application.

  2. Your controllers shoud not be of singleton scope. They should be either request or session scoped. Your service layer should consist of singletons

  3. If your controller is singleton it is pretty certain that the whole thing will be messed up ;)

Bozho
Thanks for the answer. Maybe you also know some articles where this things described? P.S. it's not 'my controller', I'm just investigating existing project.
Roman
here's a wonderful how-to for spring+jsf+hibernate http://thelabdude.blogspot.com/2009/04/user-authentication-registration-with.html
Bozho
Nice article with number of useful things.
Roman
A: 

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

Mike Q
+2  A: 

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.

BalusC
Looks sensible. In described project I see the situation as in your first block of code.
Roman