简体   繁体   中英

Thread safety in JSF

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 ie 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?

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, ie declared in the method block. Eg

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.

  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 singleton s

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM