我有两个应用程序作用域bean,它们在启动时初始化。两者都用
注释@ManagedBean(eager=true)
@ApplicationScoped
问题是,一个bean必须在另一个bean之前实例化并"postconstruct"。有办法做到这一点吗?
第一个选项将是做一个单例
@ManagedBean
@ApplicationScoped
public class SingletonBean
{
private static SingletonBean m_oInstance;
public static SingletonBean getInstance()
{
if(m_oInstance == null)
{
m_oInstance = (SingletonBean)FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get("singletonBean");
// Just in case our instance is not already in the FacesContext
if(m_oInstance == null)
{
m_oInstance = new SingletonBean();
FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put("singletonBean",m_oInstance);
}
}
return m_oInstance;
}
}
你只需要从其他bean调用它:
SingletonBean.getInstance();
第二个选项我刚刚测试过,它看起来不是最优雅的,但可以完成这项工作是通过将@ManagedProperty
添加到需要在second中加载的所有@ApplicationScoped
bean,它允许在第一时间强制加载第一个bean。
第一bean
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationScopeZ
{
public ApplicationScopeZ()
{
System.out.println("ApplicationScopeZ - constructor");
}
@PostConstruct
private void init()
{
System.out.println("ApplicationScopeZ - init");
}
}
第二个bean
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationScopeA
{
@ManagedProperty(value="#{applicationScopeZ}")
ApplicationScopeZ applicationScopeZ;
public ApplicationScopeA()
{
System.out.println("ApplicationScopeA - constructor");
}
@PostConstruct
private void init()
{
System.out.println("ApplicationScopeA - init");
}
public void setapplicationScopeZ(ApplicationScopeZ p_oApplicationScopeZ)
{
applicationScopeZ = p_oApplicationScopeZ;
}
}
第三bean @ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationScopeO
{
@ManagedProperty(value="#{applicationScopeZ}")
ApplicationScopeZ applicationScopeZ;
public ApplicationScopeO()
{
System.out.println("ApplicationScopeO - constructor");
}
@PostConstruct
private void init()
{
System.out.println("ApplicationScopeO - init");
}
public void setapplicationScopeZ(ApplicationScopeZ p_oApplicationScopeZ)
{
applicationScopeZ = p_oApplicationScopeZ;
}
}
使用Mojarra 2.1.14以这种配置启动应用程序,它给出如下输出:
ApplicationScopeZ - constructor
ApplicationScopeZ - init
ApplicationScopeO - constructor
ApplicationScopeO - init
ApplicationScopeA - constructor
ApplicationScopeA - init
正如我们所看到的,First bean (ApplicationScopeZ)是首先加载的,即使名称应该在末尾排序。
通过删除所有与注入相关的代码来做同样的事情,得到以下输出:
ApplicationScopeA - constructor
ApplicationScopeA - init
ApplicationScopeO - constructor
ApplicationScopeO - init
ApplicationScopeZ - constructor
ApplicationScopeZ - init
总之,注射改变了顺序