Если ваш код вызывает FacesContext , он не будет работать вне потока, связанного с жизненным циклом запроса JSF. Объект FacesContext создается для каждого запроса и располагается в конце запроса. Причина, по которой вы можете получить его с помощью статического вызова , заключается в том, что он установлен на ThreadLocal в начале запроса. Жизненный цикл FacesContext не имеет отношения к ServletContext.
Может быть, этого недостаточно (похоже, вы уже шли по этому маршруту), но вы должны иметь возможность использовать ServletContextListener, чтобы делать то, что вы хотите. Просто убедитесь, что все вызовы FacesContext хранятся в потоке запросов JSP.
web.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, вы можете получить его из ExternalContext :
FacesContext.getCurrentInstance()
.getExternalContext().getApplicationMap().get("foo");