Jsf 将视图范围的bean注入另一个视图范围的bean
只要用户与同一个视图交互(或者导航到不同的视图),视图范围的bean就保持活动状态 假设一个视图范围的托管bean被注入另一个视图范围的bean,如下所示Jsf 将视图范围的bean注入另一个视图范围的bean,jsf,managed-bean,jsf-2.2,Jsf,Managed Bean,Jsf 2.2,只要用户与同一个视图交互(或者导航到不同的视图),视图范围的bean就保持活动状态 假设一个视图范围的托管bean被注入另一个视图范围的bean,如下所示 @ManagedBean @ViewScoped public final class SharableManagedBean implements Serializable { private static final long serialVersionUID = 1L; @EJB private Sharabl
@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.
}
在这种情况下,shalablemanagedbean
是否需要一个视图范围的bean
如果它是请求范围的bean(
SharableManagedBean
),会发生什么?当TestManagedBean
出现并销毁时,当TestManagedBean
销毁时,它是否只初始化一次?即使在技术上也可以这样做(JSF允许您注入范围相同或更广的bean)我看不出用@ViewScoped
bean这样做有什么意义。在我看来,一个设计良好的JSF web应用程序应该有一个绑定到每个特定视图的@ViewScoped
bean。那么,如何解决你的问题呢?您可以通过两种方式完成:
SharableManagedBean
是一个实用程序bean,它包含不与JSF绑定的静态方法,只需将这个类定义为abstract
,并在需要时静态调用它的方法SharableManagedBean
本身必须是一个访问的托管bean,并且具有所有视图bean共享的公共代码,那么只需创建一个abstract
类,并使您的@ViewScoped
bean扩展它shalablemanagedbean
being@RequestScoped
),JSF不允许您这样做。由于尝试注入范围更窄的托管bean,您将得到一个异常
根据报告:
关于托管bean相互引用的另一个重要问题是,托管bean只能引用其他bean,前提是它们的作用域与调用对象相等或具有更长的生命周期
更新
如果使用CDI,也可以使用代理模式将
@RequestScoped
bean注入@ViewScoped
bean。拥有。是有道理的。谢谢:)。(我今天没有投票,明天就可以了。)通过CDI管理bean时,在视图范围bean中注入请求范围bean是有效的。您只需要记住,这实际上注入了一个代理,它在方法调用中为您返回当前实例,因此在postconstruct和后续表单提交期间,它不一定是同一个实例(因此,您需要手动复制postconstruct中的必要属性,如果有的话)实际上并不知道这一点。我不使用CDI,所以我需要看一看;-)