只要用户与同一视图交互(或直到导航到不同视图),视图范围的bean就会保持活动状态。
假设视图范围的托管bean被注入另一个视图范围的bean,如此,
@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.
}
在这种情况下,SharableManagedBean
是否有必要使用视图范围的bean?
如果是请求范围的bean(SharableManagedBean
)会发生什么?只有当TestManagedBean
出现并被销毁时才被初始化一次,当TestManagedBean
被销毁时?
答案 0 :(得分:4)
即使技术上可以这样做( JSF允许你注入相同或更广范围的bean )我没有看到用@ViewScoped
bean做这件事的重点。从我的角度来看,一个设计良好的JSF Web应用程序应该有一个绑定到每个特定视图的@ViewScoped
bean。那么,如何解决您的问题?你可以用两种方式做到这一点:
SharableManagedBean
是一个实用程序bean,它包含与JSF无关的静态方法,只需将此类定义为abstract
,并在每次需要时静态调用其方法。SharableManagedBean
本身必须是一个访问FacesContext
的托管bean,并且具有在所有视图bean中共享的公共代码,那么只需创建一个abstract
类并创建{ {1}} bean扩展它。对于您的上一个问题(@ViewScoped
为SharableManagedBean
),JSF不允许您这样做。你会因为尝试注入一个范围更窄的托管bean而获得异常。
根据Oracle docs:
关于托管bean彼此引用的另一个重要观点是托管bean只能引用其他bean,因为它们的范围相等或者具有比调用对象更长的生命周期。
更新
如果使用CDI ,则可以使用代理模式将@RequestScoped
bean注入@RequestScoped
。有it a look。