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

2022-09-02 04:34:36

我想知道是否有人可以建议:我有一个场景,Quartz运行的调度作业将每小时更新一次对象数组列表。

但是我需要这个对象数组列表对Tomcat创建的所有会话可见。因此,我的想法是,我每小时从运行的 Quartz 作业的某个位置写入此对象,以便每个会话都可以访问它。

谁能说这能以最佳方式实现?我想知道从Quartz工作写入servlet上下文的对象?另一种方法是让每个会话填充数据库表中对象的数组列表。

谢谢

摩根先生。


答案 1

是的,我会将列表存储为应用程序范围的属性。相反,从数据库中提取数据的效率可能较低,因为您只是每小时更新一次列表。为了向 Quartz 任务提供对对象的引用,可能需要创建 a。只能从 JavaEE 相关的类(如 Servlets 和侦听器)中检索。ServletContextServletContextListenerServletContextServletContext

编辑:在 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");
    //...
  }
}

答案 2

您可以尝试一些缓存解决方案,例如EhCache来存储您的值,并每小时更新一次。它将处理并发问题。缓存对象本身可以存储在ServletContext

写入 from Quartz 作业的一个好方法是将侦听器注册到您的作业,这些侦听器会收到有关已更改值的通知。例如:ServletContext

public class JobListener {
    public void updateValue(Object newValue);
}

public class ServletContextCacheJobListener implements JobListener {
     private ServletContext ctx;
     public ServletContextJobListener(ServletContext ctx) {
         this.ctx = ctx;
     }

     public void updateValue(Object newValue) {
          Cache cache = (Cache) ctx.getAttribute("cache");
          cache.update("yourKey", newValue);
     }
}

您的作业将具有一个,当您计划作业时,您将实例化具体的侦听器并将其添加到作业中。List<JobListener>


推荐