@Inherited @Documented @NormalScope(passivating=true) @Retention(value=RUNTIME) @Target(value={TYPE,METHOD,FIELD}) public @interface ViewScoped
The CDI view scope annotation, with more optimal handling of bean destroy as compared to standard JSF one.
In standard JSF 2.0/2.1, the PreDestroy
annotated method on a view scoped bean was never invoked when
the session expires. Since OmniFaces 1.6, this CDI view scope annotation will guarantee that the PreDestroy
annotated method is also invoked on session expire. Since JSF 2.2, this problem is solved on native JSF view scoped
beans, hereby making this annotation superflous in JSF 2.2.
However, there may be cases when it's desirable to immediately destroy a view scoped bean as well when the browser
unload
event is invoked. I.e. when the user navigates away by GET, or closes the browser tab/window.
None of the both JSF 2.2 view scope annotations support this. Since OmniFaces 2.2, this CDI view scope annotation
will guarantee that the PreDestroy
annotated method is also invoked on browser unload. This trick is done by
a synchronous XHR request via an automatically included helper script omnifaces:unload.js
. There's
however a small caveat: on slow network and/or poor server hardware, there may be a noticeable lag between the
enduser action of unloading the page and the desired result. If this is undesireable, then better stick to JSF 2.2's
own view scope annotations and accept the postponed destroy.
In a nutshell: if you're on JSF 2.0/2.1, and you can't upgrade to JSF 2.2, and you want the PreDestroy
to be
invoked on sesison expire too, then use OmniFaces 1.6+ with this view scope annotation. Or, if you're on JSF 2.2
already, and you want the PreDestroy
to be invoked on browser unload too, then use OmniFaces 2.2+ with this
view scope annotation.
Related JSF issues:
import javax.inject.Named; import org.omnifaces.cdi.ViewScoped; @Named @ViewScoped public class OmniCDIViewScopedBean implements Serializable {}
Please note that the bean must implement Serializable
, otherwise the CDI implementation
will throw an exception about the bean not being passivation capable.
Under the covers, CDI managed beans with this scope are via ViewScopeManager
stored in the session scope by
an UUID
based key which is referenced in JSF's own view map as available by UIViewRoot.getViewMap()
.
They are not stored in the JSF view map itself as that would be rather expensive in case of client side state saving.
By default, the maximum number of active view scopes is hold in a LRU map with a default size equal to the first non-null value of the following context parameters:
If none of those context parameters are present, then a default size of
20 will be used. When a view scoped
bean is evicted from the LRU map, then its PreDestroy
will also guaranteed to be invoked.
ViewScopeExtension
,
ViewScopeContext
,
ViewScopeManager
,
ViewScopeEventListener
,
RestorableViewHandler
Copyright © 2012–2015 OmniFaces. All rights reserved.