将视图范围的bean注入另一个视图范围的bean

时间:2013-11-30 11:09:19

标签: 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 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被销毁时?

1 个答案:

答案 0 :(得分:4)

即使技术上可以这样做( JSF允许你注入相同或更广范围的bean )我没有看到用@ViewScoped bean做这件事的重点。从我的角度来看,一个设计良好的JSF Web应用程序应该有一个绑定到每个特定视图的@ViewScoped bean。那么,如何解决您的问题?你可以用两种方式做到这一点:

  1. 如果SharableManagedBean是一个实用程序bean,它包含与JSF无关的静态方法,只需将此类定义为abstract,并在每次需要时静态调用其方法。
  2. 如果SharableManagedBean本身必须是一个访问FacesContext的托管bean,并且具有在所有视图bean中共享的公共代码,那么只需创建一个abstract类并创建{ {1}} bean扩展它。
  3. 对于您的上一个问题(@ViewScopedSharableManagedBean),JSF不允许您这样做。你会因为尝试注入一个范围更窄的托管bean而获得异常。

    根据Oracle docs

      

    关于托管bean彼此引用的另一个重要观点是托管bean只能引用其他bean,因为它们的范围相等或者具有比调用对象更长的生命周期。

    更新

    如果使用CDI ,则可以使用代理模式将@RequestScoped bean注入@RequestScoped。有it a look