如何在Java servlet上下文中获取和设置全局对象

Mr *_*gan 20 java servlets quartz-scheduler

我想知道是否有人可以建议:我有一个场景,由Quartz运行的预定作业将每小时更新一个对象的arraylist.

但我需要这些对象的arraylist对Tomcat创建的所有会话都是可见的.所以我想的是我每隔一小时从运行的Quartz作业中的某个地方写这个对象,这样每个会话都可以访问它.

任何人都可以说这可能会达到最佳效果吗?我想知道从Quartz作业写入servlet上下文的对象?另一种方法是让每个会话从数据库表中填充对象的arraylist.

谢谢

摩根先生.

Mic*_*ael 14

是的,我会将列表存储在ServletContext应用程序作用域属性中.从数据库中提取数据可能效率较低,因为您每小时只更新一次列表.ServletContextListener为了给Quartz任务提供ServletContext对象的引用,可能需要创建一个.将ServletContext只能从JavaEE的相关类,如Servlet和侦听器检索.

编辑:在ServletContextListener中,创建作业时,可以通过将列表添加到JobDataMap将列表传递给作业.

public class MyServletContextListener implements ServletContextListener{
  public void contextInitialized(ServletContextEvent event){
    ArrayList list = new ArrayList();

    //add to ServletContext
    event.getServletContext().setAttribute("list", list);

    JobDataMap map = new JobDataMap();
    map.put("list", list);
    JobDetail job = new JobDetail(..., MyJob.class);
    job.setJobDataMap(map);
    //execute job
  }

  public void contextDestroyed(ServletContextEvent event){}
}

//Quartz job
public class MyJob implements Job{
  public void execute(JobExecutionContext context){
    ArrayList list = (ArrayList)context.getMergedJobDataMap().get("list");
    //...
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 看一下另一个答案的评论,看起来你已经有了一个启动Quartz任务的ServletContextListener?您可以做的是在侦听器中创建列表,然后将列表作为属性添加到ServletContext,然后将相同的列表传递给任务.然后,您可以通过调用"ServletContext#getAttribute()"来访问Web应用程序中的任何位置.例如,在servlet中,您将调用`(ArrayList)getServletContext().getAttribute("list")`.确保正确同步列表,以便您不会同时读取/写入列表. (2认同)