@Inherited @Documented @NormalScope(passivating=true) @Retention(value=RUNTIME) @Target(value={TYPE,METHOD,FIELD}) public @interface ViewScoped
The CDI view scope annotation, intented for use in JSF 2.0/2.1. Just use it the usual way as all other CDI scopes. Watch out with IDE autocomplete on import that you don't accidentally import 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.
In JSF 2.2, you're supposed to use JSF's own new CDI compatible javax.faces.view.ViewScoped
instead;
not because this CDI view scope annotation is so bad, in contrary, but just because using the standard solutions
should be preferred over alternative solutions if they solve the same problem.
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.
In effects, this CDI view scope annotation has exactly the same lifecycle as JSF's own view scope. One important
thing to know and understand is that any PreDestroy
annotated method on a CDI view scoped bean isn't
immediately invoked in all cases when the view scope ends. This is not specific to CDI, but to JSF itself.
For detail, see the following JSF issues related to the matter:
Summarized, it's only immediately invoked when the view is either explicitly changed by a non-null/void
navigation on a postback, or when the view is explicitly rebuilt by FacesContext.setViewRoot(UIViewRoot)
.
It's not immediately invoked on a GET navigation, nor a close of browser tab/window. This CDI view scope
annotation however guarantees that the PreDestroy
annotated method is also invoked on session expire, while
JSF 2.0/2.1 doesn't do that (JSF 2.2 does).
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