Java JSF在初始化上下文时初始化应用程序范围bean
我正在构建一个JSF+Facelets web应用程序,其中的一部分是一个方法,它每隔一段时间扫描一个目录,并对任何更改进行索引。此方法是应用程序范围内bean的一部分。我已经构建了TimerTask的子类,以便每X毫秒调用一次该方法。我的问题是初始化bean。我可以在页面上引用bean,当我转到页面时,bean被初始化,并按照指示工作;相反,我希望在初始化web上下文时初始化bean,这样就不需要访问页面来启动索引方法。Google已经向一些人展示了这个功能,但是除了与Spring集成之外,没有真正的解决方案,我真的不想仅仅为了获得这个功能就这么做 我尝试过使用设置了“启动时加载”的servlet和一个ServletContextListener来进行设置,但由于没有可用的FacesContext,或者因为我无法从JSF环境引用bean,所以未能正确设置Java JSF在初始化上下文时初始化应用程序范围bean,java,jsf,Java,Jsf,我正在构建一个JSF+Facelets web应用程序,其中的一部分是一个方法,它每隔一段时间扫描一个目录,并对任何更改进行索引。此方法是应用程序范围内bean的一部分。我已经构建了TimerTask的子类,以便每X毫秒调用一次该方法。我的问题是初始化bean。我可以在页面上引用bean,当我转到页面时,bean被初始化,并按照指示工作;相反,我希望在初始化web上下文时初始化bean,这样就不需要访问页面来启动索引方法。Google已经向一些人展示了这个功能,但是除了与Spring集成之外,没
有没有办法在web应用程序启动时初始化JSF bean?使用侦听器或启动时加载,尝试以下操作:如果您的代码调用,它将无法在与JSF请求生命周期关联的线程之外工作。为每个请求创建一个FacesContext对象,并在请求结束时释放。您可以通过获取它的原因是,它在请求开始时被设置为。FacesContext的生命周期与ServletContext的生命周期无关 也许这还不够(听起来你已经走了这条路),但是你应该能够使用ServletContextListener来做你想做的事情。只需确保对FacesContext的任何调用都保存在JSP的请求线程中 web.xml:
<listener>
<listener-class>appobj.MyApplicationContextListener</listener-class>
</listener>
您可以通过JSF应用程序作用域来处理此对象(或者如果没有其他同名变量,则直接处理):
在JSF2+中,您可以使用
SystemEventListener
来处理它。您可以将其设置为对postconstructionapplicationevent
执行操作以对其进行初始化
<system-event-listener>
<system-event-listener-class>
listeners.SystemEventListenerImpl
</system-event-listener-class>
<system-event-class>
javax.faces.event.PostConstructApplicationEvent
</system-event-class>
</system-event-listener>
这将允许您做更多的事情,而不仅仅是简单地传递一个值。我以前使用过这个技巧,但它不适用于ServletContextListener,因为您没有facesContext=contextFactory.getFacesContext(servletContext,request,response,lifecycle)的请求/响应;如果任何参数为null,则失败。启动时加载/init.I的问题也一样,最好/更容易的方法是在启动时创建类并存储它。然后,当第一次访问jsf bean时,它将检查该类并使用它,或者将数据从一个类复制到另一个类。这最终解决了—我缺少了“setAttribute”位,以便在jsf代码中访问它。谢谢请注意,OP使用的是JSF1.x(当提出问题时,JSF2.x并不存在)。对于JSF2.x,顺便说一句,有一种更简单的方法:只需一个
@ManagedBean(eager=true)@ApplicationScoped
。不需要XML或接口混乱。请看,我回去阅读了这个问题,您的回答解决了他问题的最后一部分,关于JSF2.x的急切加载。抢手货
<f:view>
<h:outputText value="#{applicationScope.foo.value}" />
<h:outputText value="#{foo.value}" />
</f:view>
FacesContext.getCurrentInstance()
.getExternalContext().getApplicationMap().get("foo");
<system-event-listener>
<system-event-listener-class>
listeners.SystemEventListenerImpl
</system-event-listener-class>
<system-event-class>
javax.faces.event.PostConstructApplicationEvent
</system-event-class>
</system-event-listener>
public class SystemEventListenerImpl implements SystemEventListener {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
Application application = (Application) event.getSource();
//TODO
}
@Override
public boolean isListenerForSource(Object source) {
return (source instanceof Application);
}
}