ejb3 定时器开发
定时服务用作在一段特定的时间后执行某段程序,估计各位在不同的场合中已经使用过。下面就直接介绍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脚本
上一篇: C#自动生成漂亮的水晶效果头像的实现代码
下一篇: 排序算法之希尔排序及Java实现