If your code calls FacesContext, it will not work outside a thread associated with a JSF request lifecycle. A FacesContext object is created for every request and disposed at the end of the request. The reason you can fetch it via a static call is because it is set to a ThreadLocal at the start of the request. The lifecycle of a FacesContext bears no relation to that of a ServletContext.
Maybe this isn't enough (it sounds like you've already been down this route), but you should be able to use a ServletContextListener to do what you want. Just make sure that any calls to the FacesContext are kept in the JSP's request thread.
web.xml:
<listener>
<listener-class>appobj.MyApplicationContextListener</listener-class>
</listener>
Implementation:
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();
}
}
}
You can address this object via the JSF application scope (or just directly if no other variable exists with the same name):
<f:view>
<h:outputText value="#{applicationScope.foo.value}" />
<h:outputText value="#{foo.value}" />
</f:view>
If you wish to retrieve the object in a JSF managed bean, you can get it from the ExternalContext:
FacesContext.getCurrentInstance()
.getExternalContext().getApplicationMap().get("foo");
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…