是否可以在应用程序启动时从TimerTask或ScheduledExecutorService引用FacesContext?

时间:2011-12-07 21:26:02

标签: jsf jdeveloper facescontext

我正在尝试在JSF1.2 / ADF网络应用程序中创建功能,该应用程序将定期和动态生成网站的站点地图,该网站将包含数百个内容每天都会更改的网页。问题是,我需要从应用程序中读取一些配置作为站点地图的基础,为此,我需要FacesContext。

这是我试图做的:我创建了一个实现ServletContextListener的类,并实例化了一个应用程序范围的bean。这个bean使用FacesContext来创建sitemap.xml。我创建了一个扩展TimerTask的类,它从应用程序范围访问bean,调用sitemap方法并安排将来的事件。当我运行应用程序时,实现ServletContextListener的类将触发并且似乎创建了bean,但是从不触发扩展TimerTask的类。任何帮助,将不胜感激。如果我可以回答任何问题或者我遗漏了什么,请告诉我。

以下是我的代码示例:

public class WebhomesApplicationContextListener implements ServletContextListener {
 private static final String attribute = "SiteMapGenerator";
  public void contextInitialized(ServletContextEvent event) {
  SiteMapGenerator myObject = new SiteMapGenerator();
  event.getServletContext().setAttribute(attribute, myObject);
 }
 public void contextDestroyed(ServletContextEvent event) {
  SiteMapGenerator myObject = (SiteMapGenerator) event.getServletContext().getAttribute(attribute);
  event.getServletContext().removeAttribute(attribute);
 }
}

public class SiteMapGenerator {
 public void generateSitemap() {
   // code to generate map...
 }
}

public class Scheduler extends TimerTask {
 public void run() {
  SiteMapGenerator sitemap = (SiteMapGenerator)FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get("SiteMapGenerator");
  sitemap.generateSitemap();
 }
}

class MainApplication {
 public static void main(String[] args) {
  Timer timer = new Timer();
  timer.schedule(
   new Scheduler(),
   1000 * 60);
 }
}

1 个答案:

答案 0 :(得分:2)

不,你不能。 FacesContext仅在与HTTP servlet请求关联的线程中可用,其URL与FacesServlet的URL模式匹配并已调用它。相反,只需将SiteMapGenerator传递给Scheduler进行构建。

public class Scheduler {

    private SiteMapGenerator sitemap;

    public Scheduler(SiteMapGenerator sitemap) {
        this.sitemap = sitemap;
    }

    // ...
}

您构建SiteMapGenerator时肯定可以使用Scheduler


对具体问题

无关,强烈建议不要在Java EE应用程序中使用TimerTask。另请参阅Spawning threads in a JSF managed bean for scheduled tasks using a timer