上下文初始化时,JSF初始化应用程序范围bean

我正在构建一个JSF + Facelets Web应用程序,其中一个是每隔一段时间扫描一个目录并为任何更改编制索引的方法。 此方法是应用程序范围内的bean的一部分。 我已经构建了一个TimerTask的子类来每隔X毫秒调用一次该方法。 我的问题是初始化bean。 我可以在页面上引用bean,当我转到页面时,bean被初始化,并按照指示工作; 我想要的是在初始化Web上下文时初始化bean,这样它就不需要页面访问来启动索引方法。 谷歌已经展示了一些人想要这个function,但除了与Spring集成之外没有真正的解决方案,我真的不想仅仅为了获得这个function。

我已经尝试过使用具有“load-on-startup”设置的servlet和一个ServletContextListener来处理事情,并且无法正确设置,因为没有FacesContext可用,或者因为我无法从JSF环境引用bean。

有没有办法在Web应用程序启动时初始化JSF bean?

如果您的代码调用FacesContext ,它将无法在与JSF请求生命周期关联的线程之外工作。 为每个请求创建一个FacesContext对象,并在请求结束时进行处理。 您可以通过静态调用获取它的原因是因为它在请求开始时设置为ThreadLocal 。 FacesContext的生命周期与ServletContext的生命周期无关。

也许这还不够(听起来你已经走了这条路),但是你应该能够使用ServletContextListener来做你想做的事情。 只需确保对FacesContext的任何调用都保存在JSP的请求线程中。

web.xml中:

 appobj.MyApplicationContextListener  

执行:

 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应用程序范围来解决此对象(或者如果没有其他变量存在同名,则直接解决):

     

如果您希望在JSF托管bean中检索对象,可以从ExternalContext获取它:

 FacesContext.getCurrentInstance() .getExternalContext().getApplicationMap().get("foo"); 

使用侦听器或加载启动时,请尝试以下操作: http : //www.thoughtsabout.net/blog/archives/000033.html

在JSF 2+中,您可以使用SystemEventListener来处理它。 您可以将其设置为对PostConstructApplicationEvent执行操作以对其进行初始化。

   listeners.SystemEventListenerImpl   javax.faces.event.PostConstructApplicationEvent   

实现看起来像:

 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); } } 

这将允许您做更多的事情,而不仅仅是传递一个值。