@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.
Since OmniFaces 2.3, the unload has been further improved to also physically remove the associated JSF view state
from JSF implementation's internal LRU map in case of server side state saving, hereby further decreasing the risk
at ViewExpiredException
on the other views which were created/opened earlier. As side effect of this
change, the @PreDestroy
annotated method of any standard JSF view scoped beans referenced in the
same view as the OmniFaces CDI view scoped bean will also guaranteed be invoked on browser unload.
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:
Just use it the usual way as all other CDI scopes. Watch out with IDE autocomplete on import that you don't accidentally import standard JSF's own one.
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
,
BeanStorage
,
RestorableViewHandler
,
OmniExternalContext
,
OmniExternalContextFactory
Copyright © 2012–2016 OmniFaces. All rights reserved.