Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSF在初始化上下文时初始化应用程序范围bean_Java_Jsf - Fatal编程技术网

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

Java JSF在初始化上下文时初始化应用程序范围bean,java,jsf,Java,Jsf,我正在构建一个JSF+Facelets web应用程序,其中的一部分是一个方法,它每隔一段时间扫描一个目录,并对任何更改进行索引。此方法是应用程序范围内bean的一部分。我已经构建了TimerTask的子类,以便每X毫秒调用一次该方法。我的问题是初始化bean。我可以在页面上引用bean,当我转到页面时,bean被初始化,并按照指示工作;相反,我希望在初始化web上下文时初始化bean,这样就不需要访问页面来启动索引方法。Google已经向一些人展示了这个功能,但是除了与Spring集成之外,没

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

我尝试过使用设置了“启动时加载”的servlet和一个ServletContextListener来进行设置,但由于没有可用的FacesContext,或者因为我无法从JSF环境引用bean,所以未能正确设置


有没有办法在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);
  }
}