Как получить и установить глобальный объект в контексте сервлета Java

Интересно, кто-нибудь может посоветовать: у меня есть сценарий, когда запланированное задание, запускаемое Quartz, будет обновлять список объектов каждый час.

Но мне нужно, чтобы этот массив объектов был виден всем сеансам, созданным Tomcat. Так что я думаю, что пишу этот объект где-то каждый час из задания Quartz, которое выполняется, чтобы каждый сеанс мог получить к нему доступ.

Кто-нибудь может сказать, как лучше всего этого достичь? Я задавался вопросом о записи объекта в контекст сервлета из задания Quartz? Альтернатива состоит в том, чтобы каждый сеанс заполнял массив объектов из таблицы базы данных.

Спасибо

Мистер Морган

3 ответа

Решение

Да, я бы сохранил список в ServletContext в качестве атрибута области приложения. Вместо этого извлечение данных из базы данных, вероятно, менее эффективно, поскольку вы обновляете список только каждый час. Создание ServletContextListener может потребоваться для того, чтобы дать заданию Quartz ссылку на ServletContext объект. ServletContext можно получить только из классов, связанных с 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");
    //...
  }
}

Вы можете попробовать какое-нибудь решение для кэширования, например EhCache, чтобы хранить ваши значения и обновлять их каждый час. Он будет решать проблемы параллелизма. Сам объект кеша может храниться в ServletContext

Хороший способ написать 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> и когда вы планируете задание, вы создаете экземпляр конкретного слушателя и добавляете его в задание.

Хорошо, если вы используете статические поля, они будут видны всем классам, загруженным одним и тем же загрузчиком классов. Я думаю, что по крайней мере сервлеты одного приложения должны пройти квалификацию. Тем не менее, это по общему признанию грязно.

Объект, который определен и гарантированно будет (более) глобальным, - это ServletContext. Это распределяется между всеми сервлетами, составляющими часть одного приложения, т.е. загружается из одного web.xml, Есть put а также get вызывает ServletContext, который позволяет вам рассматривать его как карту.

Кроме того, вам нужно найти классы, общие для всех веб-приложений, на одном сервере Tomcat. Tomcat много работает с загрузчиками, и я думаю, что разные веб-приложения будут иметь разные загрузчики. Вы можете обойти это, написав собственный класс и поместив этот класс в Tomcat common или же shared каталоги. Если я правильно понимаю это описание, эти классы будут доступны ОДИН РАЗ для всех веб-приложений.

Наконец, за пределами одного сервера Tomcat вам понадобится механизм на основе TCP/IP для связи между JVM. Но, как я понял твой вопрос, в этом не должно быть необходимости.

Другие вопросы по тегам