Doğru fasulye kapsamı nasıl seçilir?


Yanıtlar:


485

Giriş

Fasulyenin kapsamını (ömür boyu) temsil eder. Temel sunucu uygulaması web uygulamasının "kapakların altında" çalışmasına aşina olup olmadığınızı anlamak daha kolaydır: Sunucu uygulamaları nasıl çalışır? Örnekleme, oturumlar, paylaşılan değişkenler ve çoklu kullanım .


@Request/View/Flow/Session/ApplicationScoped

Bir @RequestScopedçekirdek tek bir HTTP istek yanıt döngüsü kadar uzun yaşar (bir Ajax isteğinin tek bir HTTP isteği olarak sayıldığını unutmayın). Bir @ViewScopedfasulye , herhangi bir gezinme / yönlendirme olmadan dönen null/ voidolmayan eylem yöntemlerini çağıran geri gönderme yoluyla aynı JSF görünümü ile etkileşim kurduğunuz sürece yaşar . Bir @FlowScopedakış, akış yapılandırma dosyasında kayıtlı belirtilen görünüm koleksiyonunda gezintiğiniz sürece yaşar. Bir @SessionScopedfasulye köklü HTTP oturumu olarak yaşar. Bir @ApplicationScopedfasulye uzun web uygulama çalışır gibi yaşar. CDI'nın @Modeltemel olarak bir stereotip olduğunu unutmayın @Named @RequestScoped, bu nedenle aynı kurallar geçerlidir.

Hangi kapsamın seçileceği yalnızca fasulyenin tuttuğu ve temsil ettiği verilere (duruma) bağlıdır. @RequestScopedBasit ve ajax olmayan formlar / sunumlar için kullanın . Kullanım @ViewScopedzenginler için dinamik görünüm (ajaxbased doğrulama, render, diyaloglar, vs) ajax özellikli. @FlowScopedBirden çok sayfaya yayılmış giriş verisi toplama "sihirbazı" ("anket") şablonu için kullanın . @SessionScopedOturum açan kullanıcı ve kullanıcı tercihleri ​​(dil vb.) Gibi istemciye özgü veriler için kullanın . @ApplicationScopedHerkes için aynı olan açılır listeler veya herhangi bir örnek değişkeni olmayan ve yalnızca yöntemlere sahip olan yönetilen fasulye gibi uygulama çapında veri / sabitler için kullanın .

@ApplicationScopedOturum / görüntüleme / istek kapsamındaki veriler için bir çekirdeği kötüye kullanmak, verilerin tüm kullanıcılar arasında paylaşılmasını sağlar, böylece herkes birbirinin verilerini basit bir şekilde yanlış görebilir. @SessionScopedKapsamlı verileri görüntülemek / istemek için bir çekirdeği kötüye kullanmak, tek bir tarayıcı oturumunda tüm sekmeler / pencereler arasında paylaşılmasını sağlar, böylece son kullanıcı, kullanıcı deneyimi için kötü sekmeler arasında geçiş yaptıktan sonra her görünümle etkileşimde tutarsızlıklar yaşayabilir. @RequestScopedKapsamlı verileri görüntülemek için bir çekirdeğin kötüye kullanılması , görünüm kapsamındaki verilerin her bir (ajax) geri dönüşte varsayılan olarak yeniden başlatılmasını sağlayarak, muhtemelen çalışmayan formlara neden olur ( ayrıca bkz . Burada 4. ve 5. noktalar ). Bir @ViewScopedçekirdeğin istek, oturum veya uygulama kapsamındaki veriler için kötüye kullanılması ve@SessionScoped Uygulama kapsamındaki verilerin çekirdeği istemciyi etkilemez, ancak gereksiz yere sunucu belleğini işgal eder ve düz verimsizdir.

Gerçekten düşük bir bellek alanınız yoksa ve tamamen vatansız gitmek istemiyorsanız , kapsamın performans etkilerine göre seçilmemesi gerektiğini unutmayın ; @RequestScopedistemcinin durumunu korumak için yalnızca fasulye kullanmanız ve istek parametreleriyle uğraşmanız gerekir . Ayrıca, farklı kapsamda veriler içeren tek bir JSF sayfanız olduğunda, bunları verilerin kapsamıyla eşleşen bir kapsama ayrı ayrı çekirdeklere yerleştirmenin tamamen geçerli olduğunu unutmayın. Fasulye sadece @ManagedPropertyJSF tarafından yönetilen fasulye veya @InjectCDI tarafından yönetilen fasulye durumunda birbirlerine erişebilir .

Ayrıca bakınız:


@CustomScoped/NoneScoped/Dependent

Sorunuzda bahsedilmiyor, ancak (eski) JSF de gerçek dünyada nadiren kullanılan @CustomScopedve destekliyor @NoneScoped. @CustomScopedÖzel bir başvurmalıdır Map<K, Bean>geçersiz kılınan sahip bazı geniş kapsamda uygulanması Map#put()ve / veya Map#get()fasulye yaratılış üzerinde daha fazla ince taneli kontrole sahip ve / veya yok etmek sırasını.

JSF @NoneScopedve CDI @Dependenttemelde fasulye üzerinde tek bir EL değerlendirmesi kadar yaşar. Bir fasulye özelliğine atıfta bulunan iki giriş alanına ve bir fasulye eylemine atıfta bulunan bir komut düğmesine sahip bir giriş formu hayal edin, böylece toplam üç EL ifadesiyle etkili bir şekilde üç örnek oluşturulacaktır. Biri kullanıcı adı ayarlı, biri şifre ayarlı ve diğeri de eylemin çağrıldığı. Normalde bu kapsamı yalnızca enjekte edildiği fasulye kadar yaşayacak olan fasulye üzerinde kullanmak istersiniz. Yani a @NoneScopedveya a @Dependentiçine enjekte edilirse @SessionScoped, @SessionScopedfasulye kadar yaşayacaktır .

Ayrıca bakınız:


Flaş kapsamı

Son olarak, JSF flaş kapsamını da destekler. Oturum kapsamındaki bir veri girişi ile ilişkili kısa yaşayan bir çerez tarafından desteklenir. Yönlendirmeden önce, HTTP yanıtında, oturum kapsamındaki veri girişiyle benzersiz bir şekilde ilişkilendirilmiş bir değere sahip bir çerez ayarlanır. Yönlendirmeden sonra, flash kapsam çerezinin varlığı kontrol edilecek ve çerezle ilişkili veri girişi oturum kapsamından kaldırılacak ve yönlendirilen isteğin istek kapsamına konulacaktır. Son olarak çerez HTTP yanıtından kaldırılacaktır. Bu şekilde, yeniden yönlendirilen istek, ilk istekte hazırlanan talep kapsamındaki verilere erişebilir.

Bu aslında yönetilen bir fasulye kapsamı olarak mevcut değildir, yani diye bir şey yoktur @FlashScoped. Flaş kapsamı yalnızca ExternalContext#getFlash()yönetilen fasulye ve EL'de harita olarak kullanılabilir #{flash}.

Ayrıca bakınız:


4
Ben bir başvuru düşünüyorum Cevabınız sorusuna "için nasıl ve ne zaman JSF yıkılan bir görünüm kapsamı fasulye nedir? " Burada alakalıdır.
Lii

3
@Soğuk: bu eski bir CDI kapsamıdır ve JSF 2.2 ile değiştirilmiştir @FlowScoped(manuel olarak başlatmaya / durdurmaya gerek yoktur).
BalusC

1
Ve DeltaSpike ek olarak ViewAccesscopedveWindowScoped
Kukeltje

@BalusC, bence ViewScopedMyFaces 2.2'de fasulye ile ilgili bir sorun var . Şu anda buradaViewScoped yayınladığım fasulye ve Ajax ile ilgili bir sorunla karşılaşıyorum . MyFaces JIRA'da bu konuda bir tartışma var.
Tapas Bose

CDI dört yerleşik kapsam tanımlar: @RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped açıkladığınız kapsamlar neden farklı?
Hosein Aqajani

122

JSF 2.3'ten bu yana, paket javax.faces.beanpaketinde tanımlanan tüm fasulye kapsamları , kapsamları CDI ile hizalamak için kullanımdan kaldırılmıştır. Dahası, sadece fasulyeniz @ManagedBeanek açıklama kullanıyorsa geçerlidir . 2.3'ün altındaki JSF sürümlerini kullanıyorsanız, sondaki eski yanıta bakın.


JSF 2.3'ten JSF Destek Fasulyesinde kullanılabilecek kapsamlar şunlardır:

1@javax.enterprise.context.ApplicationScoped .: Uygulama kapsamı, web uygulamasının tüm süresi boyunca devam eder. Bu kapsam tüm talepler ve tüm oturumlar arasında paylaşılmaktadır. Bu, tüm uygulama için verileriniz olduğunda kullanışlıdır.

2@javax.enterprise.context.SessionScoped .: Oturum kapsamı, bir oturumun oluşturulduğu andan oturum sonlandırmasına kadar devam eder. Oturum bağlamı, aynı HTTP oturumunda gerçekleşen tüm istekler arasında paylaşılır. Bu, belirli bir oturum için belirli bir istemciye ait verileri kaydetmeyeceğinizde kullanışlıdır.

3@javax.enterprise.context.ConversationScoped .: Konuşma kapsamı, fasulye yaşarken günlük olarak devam eder. Kapsam 2 yöntem sağlar: Conversation.begin()ve Conversation.end(). Bu yöntemler, bir fasulyenin ömrünü başlatmak veya bitirmek için açıkça çağrılmalıdır.

4@javax.enterprise.context.RequestScoped .: Talep kapsamı kısa ömürlüdür. Bir HTTP isteği gönderildiğinde başlar ve yanıt istemciye geri gönderildikten sonra sona erer. Yönetilen bir çekirdeği istek kapsamına yerleştirirseniz, her istekle yeni bir örnek oluşturulur. Oturum kapsamı depolamasının maliyeti konusunda endişeleriniz varsa istek kapsamını dikkate almaya değer.

5@javax.faces.flow.FlowScoped .: Akış kapsamı, Akış devam ettiği sürece devam eder. Akış, bir iş birimini tanımlayan bir dizi sayfa (veya görünüm) olarak tanımlanabilir. Kapsamı çizilen akış, kullanıcı Akış'ta gezintiği sürece etkindir.

6@javax.faces.view.ViewScoped .: Aynı JSF sayfası yeniden görüntülenirken görünüm kapsamındaki bir fasulye devam eder. Kullanıcı farklı bir sayfaya gider gitmez, fasulye kapsam dışına çıkar.


Aşağıdaki eski yanıt, 2.3'ten önceki JSF sürümünü uygular

JSF 2.x itibariyle 4 Fasulye Kapsamı vardır:

  • @SessionScoped
  • @RequestScoped
  • @ApplicationScoped
  • @ViewScoped

Oturum Kapsamı: Oturum kapsamı , bir oturumun oluşturulduğu andan oturum sonlandırmasına kadar devam eder. Web uygulamasının HttpSession nesnesinde geçersiz kılma yöntemini çağırması veya zaman aşımına uğraması durumunda oturum sonlandırılır.

RequestScope: İstek kapsamı kısa ömürlüdür. Bir HTTP isteği gönderildiğinde başlar ve yanıt istemciye geri gönderildikten sonra sona erer. Yönetilen bir çekirdeği istek kapsamına yerleştirirseniz, her istekle yeni bir örnek oluşturulur. Oturum kapsamı depolamasının maliyeti konusunda endişeleriniz varsa istek kapsamını dikkate almaya değer.

ApplicationScope: Uygulama kapsamı, web uygulamasının tüm süresi boyunca devam eder. Bu kapsam tüm talepler ve tüm oturumlar arasında paylaşılmaktadır. Bir web uygulamasının tüm örnekleri arasında tek bir fasulye paylaşılması gerekiyorsa, yönetilen çekirdekleri uygulama kapsamına yerleştirirsiniz. Bean, uygulamanın herhangi bir kullanıcısı tarafından ilk istendiğinde oluşturulur ve web uygulaması uygulama sunucusundan kaldırılıncaya kadar canlı kalır.

ViewScope: Görünüm kapsamı JSF 2.0'da eklendi. Aynı JSF sayfası yeniden görüntülenirken görünüm kapsamındaki bir fasulye devam eder. (JSF belirtimi, bir JSF sayfası için terim görünümünü kullanır.) Kullanıcı farklı bir sayfaya gider gitmez, çekirdek kapsam dışına çıkar.

İhtiyacınıza göre kapsamı seçin.

Kaynak: Core Java Server Faces 3. Baskı by David Geary & Cay Horstmann [Sayfa no. 51-54] resim açıklamasını buraya girin


"HttpSession nesnesindeki geçersiz kılma yöntemi" ile ne demek istediğinizi açıklığa kavuşturabilir misiniz invalidate()?
Alexander Pozdneev

1
Biraz eski ve belki cevap için geç, ama açıklığa kavuşturmak için: FacesContext.getCurrentInstance().getExternalContext().invalidateSession();"çıkış fasulye" içinde çağrılmak demek.
Roland

1
eski cevap oldu, şu anda 8 kapsam var
Ewoks

@KishorPrakash: bir süre 6 ay önce. ;-)
Kukeltje

@Kukeltje: Üzgünüm, üzereyim.
Kishor Prakash
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.