我想知道是否有人可以建议:我有一个场景,Quartz正在运行的计划作业将每小时更新对象的数组列表。
但我需要这个对象数组列表对Tomcat创建的所有会话可见。因此,我的想法是,我每小时从运行的Quartz作业中的某个位置编写此对象,以便每个会话都可以访问它。
有谁能说出实现这一目标的最佳方式吗?我想知道从Quartz任务中写入servlet上下文的对象是什么?另一种方法是让每个会话填充数据库表中的对象数组列表。
谢谢
摩根先生。
发布于 2010-07-10 03:53:31
是的,我会将该列表作为应用程序范围的属性存储在ServletContext
中。相反,从数据库中提取数据可能效率较低,因为您每小时才更新一次列表。为了给Quartz任务提供对ServletContext
对象的引用,可能需要创建一个ServletContextListener
。ServletContext
只能从Servlets和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");
//...
}
}
发布于 2010-07-10 06:03:07
您可以尝试一些缓存解决方案,如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>
,当您调度作业时,您实例化具体的侦听器并将其添加到作业中。
发布于 2010-07-10 03:48:18
嗯,如果你使用静态字段,那么它们对同一类加载器加载的所有类都是可见的。我认为至少一个应用程序的servlet最终应该是合格的。然而,无可否认,这是肮脏的。
定义并保证(更多)全局的对象是ServletContext。这在构成一个应用程序的一部分的所有web.xml
之间共享,即从相同的servlet加载。有对ServletContext的put
和get
调用,允许您将其本质上视为一个Map。
除此之外,您还需要在一个Tomcat服务器中找到所有Web应用程序通用的类。Tomcat使用加载器做了很多工作,我认为不同的Web应用程序会有不同的加载器。您可以通过编写自己的类并将该类放在Tomcat的common
或shared
目录中来解决此问题。如果我对this description的理解是正确的,那么这些类将一次性提供给所有网络应用程序。
最后,除了单个Tomcat服务器的限制之外,您还需要一些基于TCP/IP的机制来实现JVM之间的通信。但根据我对你问题的理解,这不应该是必要的。
https://stackoverflow.com/questions/3215988
复制相似问题