对于J2EE中的调度任务, 在ejb2.1推出前, 似乎只能采用一些非常途径:比如在servlet中new一个Timer.
我们急切的需要EJB的标准实现.
最近我们就遇到了这样的需求. 还好websphere升级到了6.0, 支持ejb2.1规范,在ejb2.1标准中, 提供了一个Timer Service的标准实现.
要实现Timer Service, 通常的做法就是让一个无状态sessionbean实现TimedObject接口.
- public interface TimedObject{
- public void ejbTimeout(Timer timer);
- }
一个最简单的Timer Service如下(由一个无状态sessionbean实现, home和local接口省略)
- public class DemoTimerServiceBean implements javax.ejb.SessionBean, TimedObject
- {
- private javax.ejb.SessionContext mySessionCtx;
- /**
- * getSessionContext
- */
- public javax.ejb.SessionContext getSessionContext() {
- return mySessionCtx;
- }
- /**
- * setSessionContext
- */
- public void setSessionContext(javax.ejb.SessionContext ctx) {
- mySessionCtx = ctx;
- }
- /**
- * ejbCreate
- */
- public void ejbCreate() throws javax.ejb.CreateException
- {
- }
- /**
- * ejbActivate
- */
- public void ejbActivate() {
- }
- /**
- * ejbPassivate
- */
- public void ejbPassivate() {
- }
- /**
- * ejbRemove
- */
- public void ejbRemove()
- {
- }
- public void startTimer()
- {
- TimerService ts=this.getSessionContext().getTimerService();
- Timer timer = ts.createTimer(new Date(), 1000, "timerInfo");
- }
- /* (non-Javadoc)
- * @see javax.ejb.TimedObject#ejbTimeout(javax.ejb.Timer)
- */
- public void ejbTimeout(Timer arg0)
- {
- // implements your business logic.
- System.out.println("process your business logic");
- TaskHandler.process();
- }
- }
其中startTimer()用来启动一个调度任务,当调度任务的timeout时间到来时, ejb容器回调ejbTimeout()方法.以上示例子每隔一秒执行一次ejbTimeout()方法.
需要注意的是, timer service的启动需要客户调用startTimer()方法; 并且timer service具有持久化特性, 也就是说: 如果一个timer service已经启动, 如果
服务器重新启动了, 这个timer service会继续执行(无须再次调用startTimer()方法).
其实我们可以把startTimer()方法放在ejbCreate(), 当ejb实例化的时候就启动调度. 但这需要修改一下启动调度的策略. 因为容器会根据需要调用sessionbean的
create()方法, 如果每实例化一个sessionbean,就产生一个新调度, 这显然不是我们需要的.
所以,修改的策略为:
如果已经有一个同名的timer service了, 就放弃, 否则产生一个新timer service.
- public void startTimer()
- {
- TimerService ts=this.getSessionContext().getTimerService();
- Iterator timers = ts.getTimers().iterator();
- while(timers.hasNext())
- {
- Timer timer = (Timer)timers.next();
- String info = (String)timer.getInfo();
- System.out.println("timer info = " + info);
- if (info.equals("timerInfo"))
- {
- System.out.println("there is already a timer = timerInfo, so return");
- return;
- }
- }
- ts.createTimer(new Date(), 1000, "timerInfo");
- }
贴一个完整的timer service实现供有需要的人参考, 包括启动, 停止timer service(由一个无状态sessionbean实现, home和local接口省略)
- public class DemoTimerServiceBean implements javax.ejb.SessionBean, TimedObject
- {
- private static final String CONGIG_BEAN_NAME = "configBean";
- private javax.ejb.SessionContext mySessionCtx;
- /**
- * getSessionContext
- */
- public javax.ejb.SessionContext getSessionContext() {
- return mySessionCtx;
- }
- /**
- * setSessionContext
- */
- public void setSessionContext(javax.ejb.SessionContext ctx) {
- mySessionCtx = ctx;
- }
- /**
- * ejbCreate
- */
- public void ejbCreate() throws javax.ejb.CreateException
- {
- }
- /**
- * ejbActivate
- */
- public void ejbActivate() {
- }
- /**
- * ejbPassivate
- */
- public void ejbPassivate() {
- }
- /**
- * ejbRemove
- */
- public void ejbRemove()
- {
- }
- public void stopAllTimer()
- {
- TimerService ts=this.getSessionContext().getTimerService();
- Iterator timers = ts.getTimers().iterator();
- while(timers.hasNext())
- {
- Timer timer = (Timer)timers.next();
- timer.cancel();
- }
- }
- public void stopTimer(String timerName)
- {
- TimerService ts=this.getSessionContext().getTimerService();
- Iterator timers = ts.getTimers().iterator();
- while(timers.hasNext())
- {
- Timer timer = (Timer)timers.next();
- String info = (String)timer.getInfo();
- System.out.println("timer info = " + info);
- if (info.equals(timerName))
- {
- System.out.println("there is already a timer = " + timerName + ", so we cancel it!");
- timer.cancel();
- }
- }
- }
- public ArrayList getAllTimerInfo()
- {
- ArrayList timerList = new ArrayList();
- TimerService ts=this.getSessionContext().getTimerService();
- Iterator timers = ts.getTimers().iterator();
- while(timers.hasNext())
- {
- Timer timer = (Timer)timers.next();
- String info = (String)timer.getInfo();
- timerList.add(info);
- }
- return timerList;
- }
- public void startTimer()
- {
- Object configobj = MyBeanFactory.instance().getBean(CONGIG_BEAN_NAME);
- if (configobj == null)
- {
- System.out.println("Can't get configBean from spring config file. config == null");
- return;
- }
- Config config = (Config)configobj;
- long interval = config.getInterval();
- String timerInfo = config.getTimerInfo();
- this.stopTimer(timerInfo);
- System.out.println("start a timer and info = " + timerInfo + ", interval = " + interval);
- TimerService ts=this.getSessionContext().getTimerService();
- Timer timer = ts.createTimer(new Date(), interval, timerInfo);
- }
- /* (non-Javadoc)
- * @see javax.ejb.TimedObject#ejbTimeout(javax.ejb.Timer)
- */
- public void ejbTimeout(Timer arg0)
- {
- // TODO Auto-generated method stub
- System.out.println("in ejbTimeout now.");
- TaskHandler.process();
- }
- }