Как запустить таймер EJB при развертывании?

Мне нужно создать интервальный таймер, который настроен на автоматический запуск один раз в неделю. Я не хочу, чтобы он запускался на основе пользовательского ввода, но я хочу, чтобы он создавался при развертывании приложения на сервере. Каждый пример, который я видел, имеет другой класс, запускающий таймер. Я не хочу использовать bean-компонент, управляемый сообщениями, для создания таймера, потому что аудит должен просто запрашивать базу данных за заданный период времени и не основываться на действиях, которые отправляют сообщения.

Я включил пример таймера. В приведенном ниже примере таймер должен срабатывать каждые 10 минут. В качестве теста я хочу, чтобы таймер срабатывал каждые 10 минут, чтобы я мог проверить таймер.

@Stateless
public class TimerTest implements
        TimerTestLocal, TimerTestRemote{

    @Resource 
    private TimerService timerService;
    private Logger log = Logger.getLogger(TimerTest.class);
    private long interval = 1000 * 60 * 10;
    private static String TIMER_NAME = "AuditTimer";

    public void scheduleTimer() throws NamingException {
        // TODO Auto-generated method stub
        Calendar cal = Calendar.getInstance();
        //cal.set(Calendar.HOUR_OF_DAY, 23);//run at 11pm
        //cal.set(Calendar.MINUTE, 00);
        //cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm");
        log.debug("schedule for: " + sdf.format(cal.getTime()));

        timerService.createTimer(cal.getTime(), interval, TIMER_NAME);
    }

    public void cancelTimer() {
        for(Object obj : timerService.getTimers())
        {
            Timer timer = (Timer)obj;
            if(timer.getInfo().equals(TIMER_NAME))
                timer.cancel();
        }
    }

    @Timeout
    public void timerEvent(Timer timer) {
        log.debug("timer fired");
    }


}

Итак, есть ли способ запустить этот таймер при развертывании приложения? Я не думаю, что это хорошая идея помещать создание Timer в метод @PostConstruct из-за загрузчиков классов на сервере.


person scheibk    schedule 12.08.2009    source источник


Ответы (3)


Раньше я делал таймеры, создавая прослушиватель контекста в файле web.xml для настройки таймера.

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

person Jesse    schedule 12.08.2009

Если ваш проект может использовать jee6/ejb3.1, есть гораздо лучшее решение этой проблемы. http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html

@javax.ejb.Schedule(minute="*/10", hour="*")
public void automaticTimeout() {
    logger.info("Automatic timeout occured");
}

Используя новую аннотацию @Schedule, вы можете полностью контролировать, когда и как часто будет вызываться метод тайм-аута. Большой плюс: вам больше не нужно запускать таймер «снаружи».

Оракл пишет:

Автоматические таймеры создаются контейнером EJB при развертывании корпоративного компонента, содержащего методы, аннотированные аннотациями @Schedule или @Schedules. Корпоративный компонент может иметь несколько автоматических методов тайм-аута, в отличие от программного таймера, который допускает только один метод, аннотированный аннотацией @Timeout в классе корпоративного компонента.

person seafoxx    schedule 01.12.2011
comment
Чтобы ответить на ваш другой вопрос - person seafoxx; 08.11.2012

Я не знаю, может ли работать использование contextListener для запуска таймера. Из этой статьи как использовать таймер EJb 3 в кластере weblogic 10, похоже, вы можете столкнуться с некоторыми проблемами в weblogic 10.3.2.

person Mike    schedule 01.11.2010
comment
Я обнаружил ту же проблему в JBoss EAP 5.1. EJB недоступен во время вызова прослушивателя контекста. - person mekondelta; 05.09.2016