Ответ 1
То, как я делал таймеры в прошлом, заключается в создании контекстного прослушивателя в web.xml для настройки таймера.
Таким образом, вы можете убедиться, что он запущен с контейнером, и закрыть приложение при отключении приложения.
Мне нужно создать временной таймер, который будет запускаться раз в неделю автоматически. Я не хочу, чтобы он начинался с пользовательского ввода, но я хочу, чтобы он был создан, когда приложение развертывается на сервере. Каждый пример, который я видел, имеет другой класс, запускающий таймер. Я не хочу использовать управляемый сообщениями 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");
}
}
Итак, есть ли способ запустить этот таймер при развертывании приложения? Я не думаю, что было бы неплохо поместить создание таймера в метод @PostConstruct из-за загрузки классов на сервере.
То, как я делал таймеры в прошлом, заключается в создании контекстного прослушивателя в web.xml для настройки таймера.
Таким образом, вы можете убедиться, что он запущен с контейнером, и закрыть приложение при отключении приложения.
Если ваш проект может использовать 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, вы имеете обширный контроль о том, когда и как часто будет вызываться метод тайм-аута. Большой потенциал: вам больше не нужно запускать таймер "извне".
Oracle пишет:
Автоматические таймеры создаются контейнером EJB, когда предприятие bean, который содержит методы, аннотированные с помощью @Schedule или @Schedules аннотации развернуты. Предприятие bean может иметь несколько автоматические методы тайм-аута, в отличие от программного таймера, который позволяет только один метод, аннотированный аннотацией @Timeout в enterprise bean.
Я не знаю, может ли использование contextListener запускать таймер. Из этой статьи как использовать таймер EJb 3 в кластере weblogic 10, похоже, что вы можете столкнуться с некоторыми проблемами в weblogic 10.3.2.