我需要创建一个间隔计时器,设置为每周运行一次。我不希望它基于用户输入启动,但我希望在将应用程序部署到服务器时创建它。我见过的每个例子都有另一个类启动计时器。我不想使用消息驱动的bean来创建计时器,因为审计应该只查询数据库一段给定的时间,而不是基于发送消息的动作。
我已经包含了一个Timer的例子。在下面的示例中,计时器应每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方法中创建Timer是个好主意。
答案 0 :(得分:24)
如果您的项目可以使用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容器创建 包含使用@Schedule或@Schedules注释的方法的bean 注释已部署。企业bean可以有多个 自动超时方法,与程序计时器不同,它允许 只有一个方法用@Timeout注释注释 企业bean类。
答案 1 :(得分:16)
我过去做过计时器的方法是在web.xml中创建一个上下文监听器来配置计时器。
通过这种方式,您可以确保它以容器启动,并在应用程序关闭时干净地关闭。
答案 2 :(得分:1)
我不知道使用contextListener启动计时器是否可行。在本文how to use EJb 3 timer in a weblogic 10 cluster中,您可能会遇到weblogic 10.3.2中的一些问题。