我想知道是否有人可以提供建议:我有一个场景,Quartz运行的预定作业每小时都会更新一个对象的arraylist。
但我需要这些对象的arraylist对Tomcat创建的所有会话都是可见的。所以我想的是我每小时从运行的Quartz作业中的某个地方写这个对象,以便每个会话都可以访问它。
有人可以说这可以达到最佳效果吗?我想知道从Quartz作业写入servlet上下文的对象?另一种方法是让每个会话从数据库表中填充对象的arraylist。
由于
摩根先生。答案 0 :(得分:13)
是的,我会将列表存储在ServletContext
中作为应用程序范围的属性。从数据库中提取数据可能效率较低,因为您每小时只更新一次列表。可能需要创建ServletContextListener
才能为Quartz任务提供对ServletContext
对象的引用。 ServletContext
只能从与Servlet和Listeners等JavaEE相关的类中检索。
编辑: 在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");
//...
}
}
答案 1 :(得分:1)
您可以尝试一些缓存解决方案,例如EhCache来存储您的值,并每小时更新一次。它将处理并发问题。缓存对象本身可以存储在ServletContext
从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>
,当您安排作业时,您将实例化具体的侦听器并将其添加到作业中。
答案 2 :(得分:0)
好吧,如果你使用静态字段,它们对同一个类加载器加载的所有类都是可见的。我认为至少一个应用程序的servlet应该最终符合条件。然而,这无疑是肮脏的。
定义并保证(更多)全局的对象是ServletContext。这在构成一个应用程序的一部分的所有servlet之间共享,即从相同的web.xml
加载。 ServletContext有put
和get
次调用,允许您将其视为Map。
除此之外,您还需要找到一个Tomcat服务器内所有Web应用程序的通用类。 Tomcat在加载器方面做了很多步法,我认为不同的Web应用程序会有不同的加载器。您可以通过编写自己的类并将该类放在Tomcat的common
或shared
目录中来解决这个问题。如果我正确理解this description,那么这些类将可用于所有Web应用程序。
最后,除了单个Tomcat服务器的限制之外,您还需要一些基于TCP / IP的机制来在JVM之间进行通信。但是,正如我理解你的问题,这不应该是必要的。