Как получить и установить глобальный объект в контексте сервлета Java - PullRequest
19 голосов
/ 09 июля 2010

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

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

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

Спасибо

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

Ответы [ 3 ]

13 голосов
/ 09 июля 2010

Да, я бы сохранил список в ServletContext как атрибут области приложения. Вместо этого извлечение данных из базы данных, вероятно, менее эффективно, поскольку вы обновляете список только каждый час. Создание ServletContextListener может потребоваться для того, чтобы дать задаче Quartz ссылку на объект ServletContext. ServletContext можно получить только из классов, связанных с JavaEE, таких как сервлеты и прослушиватели.

EDIT: В 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 голос
/ 10 июля 2010

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

. Хороший способ записи в ServletContext из задания Quartz - это регистрация слушателей вашей работы, которые получают уведомление об измененном значении.Например:

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

0 голосов
/ 09 июля 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...