Jsf 托管Bean未在@ApplicationScoped处实例化,且eager=true

Jsf 托管Bean未在@ApplicationScoped处实例化,且eager=true,jsf,el,managed-bean,eager-loading,Jsf,El,Managed Bean,Eager Loading,我有以下UserView类: @ManagedBean(name="usersView", eager=true) @ApplicationScoped public class UserView { ... public void setUsers(...) { ... } } 然后我有另一个类,UserService,它尝试访问这个bean,然后调用这个方法,如下所示: UserView usersView = (UserView) Fac

我有以下
UserView
类:

@ManagedBean(name="usersView", eager=true)
@ApplicationScoped
public class UserView
{
    ...

    public void setUsers(...)
    {
        ...
    }
}
然后我有另一个类,
UserService
,它尝试访问这个bean,然后调用这个方法,如下所示:

UserView usersView = (UserView) FacesContext.getCurrentInstance().getExternalContext().getSessionMap("usersView");

usersView.setUsers(...)
我的问题是,
usersView
总是返回null,因此无法调用该方法

我的最终目标是在
PrimeFaces
datatable
中使用这些数据,如下所示:

<p:dataTable var="user" value="#{usersView.users}" ...>

我还尝试将范围更改为
SessionScoped
,但它仍然是空的,我不知道为什么


任何建议都将不胜感激。

如果bean还不存在,
getExternalContext().getXxxMap().get(“beanName”)
方法将不会自动创建bean。只有在计算引用bean的EL表达式时,才会自动创建托管bean。访问范围映射并不能做到这一点。为此,在源bean中使用
@ManagedProperty
。可以在EL表达式的值中指定EL表达式

@ManagedProperty("#{userView}")
private UserView userView; // +setter (no getter required).
注意,只有当源bean的作用域与目标bean的作用域相同或更窄时,这才有效。如果不是这样的话,考虑使用CDI代替JSF管理bean。然后可以使用
@Inject
而不是
@ManagedProperty
(顺便说一下,这不需要设置器)。此外,
@ManagedBean
和friends在即将发布的JSF2.3中

至于
eager=true
,这只对
@ApplicationScoped
bean有效。另见重点(我的)

如果eager()属性的值为true,且托管bean范围值为“application”,则运行时必须在应用程序启动时实例化此类。实例的实例化和存储必须在服务任何请求之前进行。如果eager未指定或为false,或者托管bean作用域不是“application”,则会发生托管bean的默认“lazy”实例化和作用域存储

另见:

为什么要从会话映射而不是应用程序映射中获取应用程序范围的bean?我以前将其作为会话范围的bean,所以忘记了更改它。尽管如此,当它确实是会话作用域时,它仍然无法从会话映射中工作。根据,
eager
仅对应用程序作用域bean有效。当它是会话作用域bean时,我如上所述删除了eager,但它仍然无法工作。我现在已经将它切换到getApplicationMap(),它工作得很好。您能解释一下为什么它作为会话范围的bean是空的,但如果这有意义的话,它现在不作为应用程序范围的bean了吗?谢谢你的帮助。再次感谢巴卢斯克,你的知识是值得称赞的!