14 декабря 2011 г.

Пишем планировщик на Java

Недавно возникла необходимость чтобы приложение в назначеное время выполняло работу по поддержке своей базы (обновляло информацию). Конечно можно было написать маленькую утилитку и вызывать её из крона, но этот вариант показался неудобным в поддержке - сервер приложений может переезжать и настраивать на каждом новом сервер крон желания не было, т.е. хотелось бы чтобы приложение само себя обслуживало, без лишних телодвижений.

К счастью существует несколько способов создать свой планировщик в enterprise-приложении. Об одном из них (а именно как это сделать с помощью ServletContextListener) я далее и расскажу.


Задача
Прежде всего напишем класс, который будет реализовывать действие, которое мы хотим поместить в планировщик. Например, мы хотим чтобы в назначеное время нам в консоль выводилась какая-либо фраза. Это можно сделать так:
public class MyTasks extends TimerTask {
 @Override
 public void run() {
  System.out.println("Hello from scheduled task!");
 }
}
Слушатель
Теперь напишем нашего слушателя:
public class TimerContextListener implements ServletContextListener {
 public void contextInitialized(ServletContextEvent sce) {
  ServletContext servletContext = sce.getServletContext();
  try {
   // create the timer and timer task objects
   Timer timer = new Timer();
   MyTasks task = new MyTasks();
   // get a calendar to initialize the start time
   Date startTime = new GregorianCalendar(2011, 1, 1, 8, 0, 0).getTime();
   // schedule the task to run daily at 8:00 am
   // startTime is in past, so task will be runned during deployment
   timer.scheduleAtFixedRate(task, startTime, 1000 * 60 * 60 * 24);
   // save our timer for later use
   servletContext.setAttribute("timer", timer);
  } catch (Exception e) {
   servletContext.log("Problem initializing the task that was to run daily: " + e.getMessage());
  }
 }
 public void contextDestroyed(ServletContextEvent sce) {
  ServletContext servletContext = sce.getServletContext();
  // get our timer from the Context
  Timer timer = (Timer) servletContext.getAttribute("timer");
  // cancel all pending tasks in the timers queue
  if (timer != null) {
   timer.cancel();
  }
  // remove the timer from the servlet context
  servletContext.removeAttribute("timer");
 }
}

Дескриптор развёртывания
Вот практически и всё. Осталось объявить этого слушателя в дескрипторе развёртывания.

 com.example.scheduler.TimerContextListener
 

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.