定时服务用作在一段特定的时间后执行某段程序,估计各位在不同的场合中已经使用过。下面就直接介绍EJB3.0
定时服务的开发过程。定时服务的开发过程与会话Bean 的开发过程大致相同,但比会话Bean 多了几个操作,那
就是使用容器对象SessionContext 创建定时器,并使用@Timeout 注释声明定时器方法。
下面定义一个每隔3 秒触发一次事件的定时器,当定时事件触发次数超过5 次的时候便终止定时器的执行
步骤1:首先写一个远程接口,主要的目的是创建一个定时器 TimerService.java
package cn.com.xinli.ejb3.task; public interface TimerService { public void scheduleTimer(long milliseconds); }
步骤2: 在定义一个无状态的会话bean,它实现了 TimerService 接口,并且使用 @Timeout 注解 表明了 当定时器工作的时候需要直接的业务方法,供容器回调使用 TimerServiceBean.java
通过依赖注入@Resource SessionContext ctx,我们获得SessionContext 对象,调用ctx.getTimerService().createTimer
(Date arg0, long arg1, Serializable arg2)方法创建定时器,三个参数的含义如下:
Date arg0 定时器启动时间,如果传入时间小于现在时间,定时器会立刻启动。
long arg1 间隔多长时间后再次触发定时事件。单位:毫秒
Serializable arg2 你需要传给定时器的参数,该参数必须实现Serializable 接口。
当定时器创建完成后,我们还需声明定时器方法。定时器方法的声明很简单,只需在方法上面加入@Timeout 注
释,另外定时器方法必须遵守如下格式:
void XXX(Timer timer)
注意:createTimer() 有4个重载的方法,分别代表不同的定时器,此例创建的是一个
每隔规定的时间反复执行的定时器,其他3种定时器 读者可以自行实验
在定时事件发生时,此方法将被执行
package cn.com.xinli.ejb3.task.impl; import java.util.Date; import javax.annotation.Resource; import javax.ejb.Remote; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.ejb.Timeout; import javax.ejb.Timer; import cn.com.xinli.ejb3.task.TimerService; @Stateless @Remote ({TimerService.class}) public class TimerServiceBean implements TimerService { private int count = 1; private @Resource SessionContext ctx; public void scheduleTimer(long milliseconds) { count = 1; ctx.getTimerService(). createTimer(new Date(new Date().getTime() + milliseconds),milliseconds, "大家好,这是我的第一个定时器"); } @Timeout public void timeoutHandler(Timer timer) { System.out.println("---------------------"); System.out.println("定时器事件发生,传进的参数为: " + timer.getInfo()); System.out.println("定时器事件发生,传进的参数为: " + timer.getNextTimeout()); System.out.println("---------------------"); if (count>=5) { timer.cancel();//如果定时器触发5次,便终止定时器 } count++; } }
步骤3:写测试用例:
package cn.com.xinli.ejb3.test; import java.util.Date; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import cn.com.xinli.ejb3.task.TimerService; public class TaskClient { public static void main(String[] args) { Hashtable evn = new Hashtable(); evn.put(Context.PROVIDER_URL, "127.0.0.1:1099"); evn.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); // Properties properties=new Properties(); // properties.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); // properties.setProperty("java.naming.provider.url", "localhost:1099"); try { System.out.println(new Date().getTime()); InitialContext ctx=new InitialContext(evn); TimerService timer = (TimerService) ctx.lookup("TimerServiceBean/remote"); timer.scheduleTimer((long)3000); System.out.println("定时器已经启动,请观察Jboss控制台输出,如果定时器触发5次,便终止定时器"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
eclipse 控制台日志:
定时器已经启动,请观察Jboss控制台输出,如果定时器触发5次,便终止定时器
jboss 日志:
08:25:02,328 INFO [STDOUT] 定时器事件发生,传进的参数为: 大家好,这是我的第一个
定时器
08:25:02,328 INFO [STDOUT] 下次触发时间为: Wed Oct 28 08:25:05 CST 2009
08:25:02,328 INFO [STDOUT] ---------------------
08:25:05,328 INFO [STDOUT] ---------------------
08:25:05,328 INFO [STDOUT] 定时器事件发生,传进的参数为: 大家好,这是我的第一个
定时器
08:25:05,328 INFO [STDOUT] 下次触发时间为: Wed Oct 28 08:25:08 CST 2009
08:25:05,328 INFO [STDOUT] ---------------------
08:25:08,328 INFO [STDOUT] ---------------------
08:25:08,328 INFO [STDOUT] 定时器事件发生,传进的参数为: 大家好,这是我的第一个
定时器
08:25:08,328 INFO [STDOUT] 下次触发时间为: Wed Oct 28 08:25:11 CST 2009
08:25:08,328 INFO [STDOUT] ---------------------
08:25:11,328 INFO [STDOUT] ---------------------
08:25:11,343 INFO [STDOUT] 定时器事件发生,传进的参数为: 大家好,这是我的第一个
定时器
08:25:11,343 INFO [STDOUT] 下次触发时间为: Wed Oct 28 08:25:14 CST 2009
08:25:11,343 INFO [STDOUT] ---------------------
08:25:14,906 INFO [STDOUT] ---------------------
08:25:14,906 INFO [STDOUT] 定时器事件发生,传进的参数为: 大家好,这是我的第一个
定时器
08:25:14,906 INFO [STDOUT] 下次触发时间为: Wed Oct 28 08:25:17 CST 2009
08:25:14,906 INFO [STDOUT] ---------------------
附件中是项目源文件和ant脚本