如果您的代码调用FacesContext,它将无法在与 JSF 请求生命周期关联的线程之外工作。为每个请求创建一个 FacesContext 对象,并在请求结束时处理。您可以通过静态调用获取它的原因是因为它在请求开始时设置为ThreadLocal。FacesContext 的生命周期与 ServletContext 的生命周期无关。
也许这还不够(听起来你已经走这条路了),但你应该能够使用 ServletContextListener 来做你想做的事。只要确保对 FacesContext 的任何调用都保存在 JSP 的请求线程中。
网页.xml:
<listener>
<listener-class>appobj.MyApplicationContextListener</listener-class>
</listener>
执行:
public class MyApplicationContextListener implements ServletContextListener {
private static final String FOO = "foo";
public void contextInitialized(ServletContextEvent event) {
MyObject myObject = new MyObject();
event.getServletContext().setAttribute(FOO, myObject);
}
public void contextDestroyed(ServletContextEvent event) {
MyObject myObject = (MyObject) event.getServletContext().getAttribute(
FOO);
try {
event.getServletContext().removeAttribute(FOO);
} finally {
myObject.dispose();
}
}
}
您可以通过 JSF 应用程序范围来处理此对象(或者如果不存在具有相同名称的其他变量,则直接处理):
<f:view>
<h:outputText value="#{applicationScope.foo.value}" />
<h:outputText value="#{foo.value}" />
</f:view>
如果您希望在 JSF 托管 bean 中检索对象,您可以从ExternalContext获取它:
FacesContext.getCurrentInstance()
.getExternalContext().getApplicationMap().get("foo");