首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Java servlet上下文中获取和设置全局对象

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

Stack Overflow用户
提问于 2010-07-10 03:39:19
回答 3查看 41.7K关注 0票数 21

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

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

有谁能说出实现这一目标的最佳方式吗?我想知道从Quartz任务中写入servlet上下文的对象是什么?另一种方法是让每个会话填充数据库表中的对象数组列表。

谢谢

摩根先生。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-07-10 03:53:31

是的,我会将该列表作为应用程序范围的属性存储在ServletContext中。相反,从数据库中提取数据可能效率较低,因为您每小时才更新一次列表。为了给Quartz任务提供对ServletContext对象的引用,可能需要创建一个ServletContextListenerServletContext只能从Servlets和Listeners等与JavaEE相关的类中检索。

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

代码语言:javascript
复制
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");
    //...
  }
}
票数 16
EN

Stack Overflow用户

发布于 2010-07-10 06:03:07

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

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

代码语言:javascript
复制
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>,当您调度作业时,您实例化具体的侦听器并将其添加到作业中。

票数 1
EN

Stack Overflow用户

发布于 2010-07-10 03:48:18

嗯,如果你使用静态字段,那么它们对同一类加载器加载的所有类都是可见的。我认为至少一个应用程序的servlet最终应该是合格的。然而,无可否认,这是肮脏的。

定义并保证(更多)全局的对象是ServletContext。这在构成一个应用程序的一部分的所有web.xml之间共享,即从相同的servlet加载。有对ServletContext的putget调用,允许您将其本质上视为一个Map。

除此之外,您还需要在一个Tomcat服务器中找到所有Web应用程序通用的类。Tomcat使用加载器做了很多工作,我认为不同的Web应用程序会有不同的加载器。您可以通过编写自己的类并将该类放在Tomcat的commonshared目录中来解决此问题。如果我对this description的理解是正确的,那么这些类将一次性提供给所有网络应用程序。

最后,除了单个Tomcat服务器的限制之外,您还需要一些基于TCP/IP的机制来实现JVM之间的通信。但根据我对你问题的理解,这不应该是必要的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3215988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档