A view scoped bean remains alive as long as the user interacts with the same view (or until it is navigated to a different view).
Suppose a view scoped managed bean is injected into another view scoped bean like so,
@ManagedBean
@ViewScoped
public final class SharableManagedBean implements Serializable
{
private static final long serialVersionUID = 1L;
@EJB
private SharableBean sharableService;
//...Do something.
}
@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable
{
private static final long serialVersionUID = 1L;
@EJB
private TestBean testBean;
@ManagedProperty(value="#{sharableManagedBean}")
private SharableManagedBean sharableManagedBean ;
//... Do something with the injected bean.
}
In this case, is it necessary for the SharableManagedBean
to have a view scoped bean?
What happens, if it is a request scoped bean (SharableManagedBean
)? Is it initialized only once, when TestManagedBean
comes into picture and destroyed, when TestManagedBean
is destroyed?
Even it's technically possible to do that (JSF allows you to inject beans which are at the same or wider scope) I don't see the point of doing that with @ViewScoped
beans. From my point of view, a well designed JSF web application should have a single @ViewScoped
bean tied to each specific view. Then, how to solve your issue? You can do it in two ways:
SharableManagedBean
is a utility bean which contain static methods which are not tied to JSF, just define this class as abstract
and statically invoke its methods everytime you need.SharableManagedBean
itself has to be a managed bean which access the FacesContext
and has common code that is shared along all the view beans, just create an abstract
class and make your @ViewScoped
beans extend it.For your last question (SharableManagedBean
being @RequestScoped
), JSF doesn't allow you doing that. You'll get an exception because of trying to inject a narrower scoped managed bean.
According to the Oracle docs:
Another important point about managed beans referencing each other is that a managed bean can only refer to other beans provide their scope is equal or has a longer lifespan than the calling object.
Update
If using CDI, it's possible to inject a @RequestScoped
bean into a @ViewScoped
one too, using the Proxy pattern. Have it a look.