2012-06-21 8 views
37

Czy wszystkie kontrolery są w singletonach Spring-MVC i są dzielone między różne sesje i żądania?Zasięg kontrolera Spring i jego zmienne instancji

Jeśli tak, zakładam, że klasa, zmienna jak

public String name; 

będzie taka sama dla wszystkich żądań i sesji? Tak więc, jeśli Użytkownik X wysyła żądanie, a name jest ustawiony na Paul, Użytkownik Z również ma Pawła jako atrybut?

W moim przypadku nie chcę tego zachowania, ale zastanawiał się, czy nie jest łatwiej, lub bardziej czystsze OOP-sposób na sesji/request-zmienne następnie session.getAttribute()/request.getAttribute()

Odpowiedz

53

Aby odpowiedzieć na pierwsze pytanie: tak , Spring kontrolery MVC domyślnie są singletons. Pole obiektu będzie udostępniane i widoczne dla wszystkich żądań i wszystkich sesji na zawsze.

Jednak bez synchronizacji można napotkać różne problemy związane z współbieżnością (warunki wyścigu, widoczność). W związku z tym twoje pole powinno mieć modyfikator volatile (i private, przy okazji), aby uniknąć problemów z widocznością.

Powrót do głównego pytania: wiosną można wykorzystać request- (patrz 4.5.4.2 Request scope) i sesyjnych-scoped (vide: 4.5.4.3 Session scope) fasoli. Możesz je wprowadzić do kontrolerów i innych fasoli (nawet pojedynczych!), Ale Spring zapewnia, że ​​każde żądanie/sesja ma niezależną instancję.

Jedyną rzeczą do zapamiętania podczas wstrzykiwania request- i sesją o zakresie fasoli w singletons jest owinąć je określania zakresów pełnomocnika (przykład wzięty z 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> 
+0

+1 Uwaga: "nawet singletony!" wymaga auto-proxying wstrzykniętych fasoli –

+0

@SeanPatrickFloyd: tak, to jest tak ważne, że dodałem przykład ze Spring docs, dzięki! –

8

Tak, kontrolery w Spring-MVC są samotnymi. Pomiędzy wieloma żądaniami zmienna klasy zostaje udostępniona i może doprowadzić do niejednoznaczności. Możesz użyć adnotacji @Scope ("request") nad kontrolerem, aby uniknąć takiej niejednoznaczności.

+0

Przykład z wyjaśnieniem byłby świetny. – Nilambar

+0

@Controller public class TestClass { \t prywatna nazwa ciągu; \t @RequestMapping ("/") \t publicznego displayName String() { \t \t if (this.name! = Null) { \t \t \t this.name = "abc"; \t } else { \t \t \t this.name = "XYZ"; \t \t} SystemOut.println (nazwa); \t \t Zwróć to.Nazwa; \t} \t public String getName() { \t \t nazwa powrotu; \t} \t public void setName (nazwa ciągu) { \t \t this.name = nazwa; \t} } } –

+0

W Kontynuacja mojej poprzedniej edycji .. Dla pierwszego żądania wydrukuje XYZ, ale dla innego równoległego żądania wydrukuje ABC, ale najlepiej jeśli dwóch użytkowników wydaje dwa różne żądania, obaj powinni zobaczyć XYZ. Wykonanie @Scope ("request") da nam pożądany rezultat. Daj mi znać, jeśli coś poszło nie tak –

Powiązane problemy