web-dev-qa-db-fra.com

Les classes MVC doivent-elles être protégées contre les threads

Si vous utilisez Spring MVC, vos classes de composants (@Controller, @Service, @Repository) être thread-safe?

Autrement dit, si j'ai un @RequestMapping méthode dans mon @Controller, cette méthode pourrait-elle être appelée simultanément pour le même objet contrôleur par plusieurs threads?

(Cela a ne sorte de question a été posée auparavant , mais n'a pas répondu comme tel).

29
Raedwald

Donné

@Controller
public class MyController {
    @RequestMapping(value = "/index")
    public String respond() {
        return "index";
    }
}

Spring créera une instance de MyController. En effet, Spring analyse votre configuration, <mvc:annotation-driven>, Voit @Controller (Qui est comme @Component) Et instancie la classe annotée. Parce qu'il voit aussi @RequestMapping, Il génère un HandlerMapping pour cela, voir docs here .

Toutes les requêtes HTTP que DispatcherServlet reçoit seront envoyées à cette instance de contrôleur via le HandlerMapping enregistré auparavant, appelant respond() à Java réflexion sur cette instance.

Si vous avez des champs d'instance comme

@Controller
public class MyController {
    private int count = 0;
    @RequestMapping(value = "/index")
    public String respond() {
        count++;
        return "index";
    }
}

count serait un danger, car il pourrait être modifié par de nombreux threads et les modifications pourraient être perdues.

Vous devez comprendre le fonctionnement des conteneurs Servlet. Le conteneur instancie une instance de votre Spring MVC DispatcherServlet. Le conteneur gère également un pool de threads qu'il utilise pour répondre aux connexions, c'est-à-dire. Demandes HTTP. Lorsqu'une telle demande arrive, le conteneur choisit un thread dans le pool et, dans ce thread, exécute la méthode service() sur le DispatcherServlet qui distribue à l'instance @Controller Correcte que Spring a enregistré pour vous (à partir de votre configuration).

Donc OUI, les classes Spring MVC doivent être thread-safe. Vous pouvez le faire en jouant avec différentes étendues pour vos champs d'instance de classe ou en ayant simplement des variables locales à la place. A défaut, vous devrez ajouter une synchronisation appropriée autour des sections critiques de votre code.

46

Par défaut, les contrôleurs sont des singletons et doivent donc être thread-safe. Cependant, vous pouvez configurer les contrôleurs pour qu'ils soient étendus à la demande ou à la session, c'est-à-dire:

@Controller
@Scope("session")
public class MyController {

    ...
}

Les contrôleurs avec étendue de session peuvent être utiles pour gérer l'état de session. Une bonne description des différents modèles peut être trouvée dans tilisation de sessions dans Spring-MVC (y compris "scoped-proxies") et dans Comment obtenir l'objet de session dans Spring MVC . Certains des modèles présentés nécessitent la portée de la demande .

La portée de la demande est également utile si vous avez des données que vous ne pouvez pas vous permettre d'en calculer plus d'une par demande.

1
Codo