Zauważyłem, że istnieją różne zakresy fasoli, takie jak:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Jaki jest cel każdego z nich? Jak wybrać odpowiedni zakres dla mojej fasoli?
jsf
jsf-2
scope
managed-bean
Valter Silva
źródło
źródło
Odpowiedzi:
Wprowadzenie
Reprezentuje zakres (czas życia) fasoli. Łatwiej to zrozumieć, jeśli znasz podstawową aplikację internetową serwletu: jak działają serwlety? Tworzenie instancji, sesje, zmienne współdzielone i wielowątkowość .
@Request/View/Flow/Session/ApplicationScoped
@RequestScoped
Fasola żyje tak długo, jak w cyklu żądanie-odpowiedź HTTP pojedynczy (zauważ, że żądania Ajax liczy się jako jedno żądanie HTTP zbyt).@ViewScoped
Fasola żyje tak długo, jak jesteś interakcji z tego samego widoku JSF przez postbacks jakie metody działania wezwanie powracającychnull
/void
bez nawigacji / przekierowania.@FlowScoped
Mieszka fasoli Dopóki jesteś przechodząc przez określony zbiór poglądów zarejestrowane w pliku konfiguracyjnym przepływu.@SessionScoped
Fasola żyje tak długo, jak długo sesji HTTP siedzibę.@ApplicationScoped
Fasola żyje tak długo, jak działa aplikacja internetowa. Należy zauważyć, że CDI@Model
jest w zasadzie stereotypu za@Named @RequestScoped
, więc stosuje się te same zasady.Wybór zakresu zależy wyłącznie od danych (stanu), które fasola przechowuje i reprezentuje. Użyj
@RequestScoped
do prostych formularzy / prezentacji innych niż ajax. Użyj@ViewScoped
dla bogatych widoków dynamicznych z włączonym systemem ajax (sprawdzanie poprawności, renderowanie, okna dialogowe itp.). Użyj@FlowScoped
do wzorca „kreatora” („kwestionariusza”) zbierania danych wejściowych rozłożonych na wielu stronach. Używaj@SessionScoped
do danych specyficznych dla klienta, takich jak zalogowany użytkownik i preferencje użytkownika (język itp.). Używaj@ApplicationScoped
do danych / stałych dla całej aplikacji, takich jak listy rozwijane, które są takie same dla wszystkich, lub zarządzanych komponentów bean bez zmiennych instancji i posiadających tylko metody.Nadużywanie komponentu
@ApplicationScoped
bean dla danych o zasięgu sesji / widoku / żądania spowodowałoby, że byłoby ono dzielone między wszystkich użytkowników, dzięki czemu każdy mógł zobaczyć dane innych użytkowników, co jest po prostu błędne. Nadużywanie komponentu@SessionScoped
bean dla danych o zasięgu / żądaniach spowodowałoby, że byłby on współużytkowany przez wszystkie karty / okna w jednej sesji przeglądarki, więc użytkownik końcowy może doświadczyć niespójności podczas interakcji z każdym widokiem po przełączeniu między kartami, co jest niekorzystne dla wygody użytkownika. Nadużywanie komponentu@RequestScoped
bean dla danych o zasięgu wyświetlania sprawiłoby, że dane o zasięgu widzenia byłyby ponownie inicjowane do wartości domyślnych przy każdym pojedynczym odsyłaniu zwrotnym (ajax), powodując prawdopodobnie niedziałające formularze ( patrz także punkty 4 i 5 tutaj ). Nadużywanie komponentu@ViewScoped
bean dla danych o zasięgu żądania, sesji lub aplikacji oraz nadużywanie@SessionScoped
komponent bean dla danych o zasięgu aplikacji nie wpływa na klienta, ale niepotrzebnie zajmuje pamięć serwera i jest po prostu nieefektywny.Zauważ, że zakres raczej nie powinien być wybierany na podstawie wpływu na wydajność, chyba że naprawdę masz mało pamięci i chcesz przejść całkowicie bezstanowo; musisz użyć wyłącznie
@RequestScoped
fasoli i skrzypce z parametrami żądania, aby utrzymać stan klienta. Należy również pamiętać, że jeśli masz jedną stronę JSF z danymi o różnym zakresie, to jest całkowicie poprawne umieszczenie ich w osobnych komponentach bean backing w zakresie pasującym do zakresu danych. Fasola może po prostu uzyskiwać do siebie dostęp@ManagedProperty
w przypadku fasoli zarządzanej przez JSF lub@Inject
w przypadku fasoli zarządzanej przez CDI.Zobacz też:
@CustomScoped/NoneScoped/Dependent
Nie wspomniano o tym w twoim pytaniu, ale (starsze) JSF obsługuje również
@CustomScoped
i@NoneScoped
, które są rzadko używane w prawdziwym świecie.@CustomScoped
Musi odnosić niestandardowąMap<K, Bean>
implementację w jakimś szerszym zakresie, który nadpisujeMap#put()
i / lubMap#get()
w celu uzyskania bardziej drobnoziarnista kontrolę nad tworzeniem fasoli i / lub zniszczyć.JSF
@NoneScoped
i CDI@Dependent
zasadniczo żyją tak długo, jak jedna ocena EL na fasoli. Wyobraź sobie formularz logowania z dwoma polami wejściowymi odnoszącymi się do właściwości komponentu bean i przyciskiem polecenia odnoszącym się do akcji komponentu bean, a więc z łącznie trzema wyrażeniami EL, a następnie utworzone zostaną trzy instancje. Jeden z ustawioną nazwą użytkownika, jeden z ustawionym hasłem i jeden, na którym wywoływana jest akcja. Zwykle chcesz używać tego lunety tylko na fasoli, która powinna żyć tak długo, jak fasola, w której jest wstrzykiwana. Więc jeśli a@NoneScoped
lub@Dependent
zostanie wstrzyknięty w a@SessionScoped
, to będzie żył tak długo, jak@SessionScoped
fasola.Zobacz też:
Luneta błyskowa
Na koniec JSF obsługuje także zakres flashowania. Jest on wspierany przez krótkotrwały plik cookie, który jest powiązany z wprowadzaniem danych w zakresie sesji. Przed przekierowaniem zostanie ustawiony plik cookie w odpowiedzi HTTP o wartości, która jest jednoznacznie związana z wprowadzaniem danych w zakresie sesji. Po przekierowaniu zostanie sprawdzona obecność pliku cookie zakresu flash, a dane powiązane z plikiem cookie zostaną usunięte z zakresu sesji i zostaną umieszczone w zakresie żądania przekierowanego żądania. Wreszcie plik cookie zostanie usunięty z odpowiedzi HTTP. W ten sposób przekierowane żądanie ma dostęp do danych o zasięgu, które zostały przygotowane w pierwszym żądaniu.
W rzeczywistości nie jest to dostępne jako zarządzany zakres komponentu bean, tzn. Nie ma czegoś takiego jak
@FlashScoped
. Luneta jest dostępna tylko jako mapaExternalContext#getFlash()
w zarządzanej fasoli i#{flash}
w EL.Zobacz też:
źródło
@FlowScoped
(nie ma potrzeby ręcznego uruchamiania / zatrzymywania).ViewAccesscoped
iWindowScoped
ViewScoped
fasolą w MyFaces 2.2. Obecnie mam do czynienia z problemem związanym zViewScoped
fasolą i Ajaxem, który opublikowałem tutaj . W MyFaces JIRA jest również dyskusja na ten temat.@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
dlaczego opisywane zakresy są różne?Od wersji JSF 2.3 wszystkie zakresy komponentu bean zdefiniowane w pakiecie
javax.faces.bean
pakietów są przestarzałe, aby wyrównać zakresy z CDI. Ponadto mają one zastosowanie tylko wtedy, gdy fasola używa@ManagedBean
adnotacji. Jeśli używasz wersji JSF poniżej 2.3, przeczytaj starszą odpowiedź na końcu.Od JSF 2.3 tutaj są zakresy, które mogą być używane na JSF Backing Beans:
1
@javax.enterprise.context.ApplicationScoped
.: Zakres aplikacji utrzymuje się przez cały czas trwania aplikacji internetowej. Ten zakres jest wspólny dla wszystkich żądań i wszystkich sesji. Jest to przydatne, gdy masz dane dla całej aplikacji.2
@javax.enterprise.context.SessionScoped
.: Zakres sesji utrzymuje się od momentu ustanowienia sesji do jej zakończenia. Kontekst sesji jest wspólny dla wszystkich żądań występujących w tej samej sesji HTTP. Jest to przydatne, gdy nie chcesz zapisywać danych dla konkretnego klienta dla określonej sesji.3
@javax.enterprise.context.ConversationScoped
.: Zakres konwersacji trwa tak długo, jak żyje fasola. Zakres obejmuje 2 metody:Conversation.begin()
iConversation.end()
. Metody te powinny być jawnie wywoływane, aby rozpocząć lub zakończyć życie fasoli.4
@javax.enterprise.context.RequestScoped
.: Zakres żądania jest krótkotrwały. Rozpoczyna się po przesłaniu żądania HTTP i kończy po odesłaniu odpowiedzi do klienta. Jeśli umieścisz zarządzaną fasolę w zakresie żądania, dla każdego żądania tworzona jest nowa instancja. Warto zastanowić się nad zakresem zapytania, jeśli obawiasz się kosztów przechowywania zakresu sesji.5
@javax.faces.flow.FlowScoped
.: Zakres Flow utrzymuje się tak długo, jak trwa Flow. Przepływ może być zdefiniowany jako zawarty zestaw stron (lub widoków), które definiują jednostkę pracy. Zasięg działania Flow jest aktywny tak długo, jak użytkownik porusza się po nim w Flow.6
@javax.faces.view.ViewScoped
.: Zasięg widoku komponentu bean utrzymuje się podczas ponownego wyświetlania tej samej strony JSF. Gdy tylko użytkownik przejdzie do innej strony, komponent bean wychodzi poza zakres.Poniższa starsza odpowiedź dotyczy wersji JSF wcześniejszej niż 2.3
Źródło: Core Java Server Faces 3. wydanie autorstwa David Geary & Cay Horstmann [Nr strony 51–54]
źródło
invalidate()
metodę, czy metodę niepoprawną?FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
bycie przywołanym w „fasoli wylogowania” jest tym, co ma na myśli.