44.13. EJB Timer Service

摘要

EJB Timer Service是一个由EJB容器管理的定时器服务程序。

44.13.1. 概述

EJB Timer Service是让用户可以基于时间调度表调用指定的程序,这种服务是由容器管理的。它可以指定事件在某一个时间点触发,也可以指定事件过多长时间然后触发,还可以指定事件以某个固定的周期来触发,这解决了在EJB容器内部几种Bean不能用多线程来达到类似功能的困难。

EJB Timer Service是一个粗粒度的时间点触发服务,它只能提供应用程序级别的时间调度和时间触发服务,不能用于精确度很高的实时系统的时间精度要求。

同时EJB Timer Service是一个可靠的、事务性的服务。

44.13.2. 组件模型单元

44.13.2.1. 接口描述

  • TimerService接口

  • TimedObject接口

  • Timer接口

  • TimerHandle接口

44.13.2.1.1. TimerService接口

TimerService的实现对象从EJBContext接口的实现获得,方法为getTimerService。TimerService接口定义了如下方法:

public interface javax.ejb.TimerService {
    public Timer createTimer(long duration,
            java.io.Serializable info);
    public Timer createTimer(long initialDuration,
            long intervalDuration, java.io.Serializable info);
    public Timer createTimer(java.util.Date expiration,
            java.io.Serializable info);
    public Timer createTimer(java.util.Date initialExpiration,
            long intervalDuration, java.io.Serializable info);
    public Collection getTimers();
}

info参数用来标识时间到期的意义和描述

getTimers返回和当前Enterprise Bean相关的Timers

44.13.2.1.2. TimedObject接口

商务逻辑实现bean对象需要实现的接口,该接口的 ejbTimeout 方法用来供Timer到期时进行回调。

public interface javax.ejb.TimedObject {
    public void ejbTimeout(Timer timer);
}
44.13.2.1.3. TimerHandle接口

该接口定义用来获得Timer对象。

public interface javax.ejb.TimerHandle extends java.io.Serializable{
    public javax.ejb.Timer getTimer();
}
44.13.2.1.4. Timer接口

该接口可以进行取消Timer的动作,也可以获得一些Timer的其它信息,例如:下次到期是什么时候,离下次到期还有多长时间等。

public interface javax.ejb.Timer {
    public void cancel();
    public long getTimeRemaining();
    public java.util.Date getNextTimeout();
    public javax.ejb.TimerHandle getHandle();
    public java.io.Serializable getInfo();
}

44.13.2.2. 功能实现框架

实现javax.ejb.TimedObject接口,javax.ejb.TimedObject接口只有一个ejbTimeout()方法,该方法就是事件到期时触发的方法,需要把Timer需要执行的商业逻辑放在该方法面里。

44.13.3. 使用EJB Timer Service

当一个bean的相关时间点到达的时候,容器将会调用该对象的ejbTimeout()方法,方法中,开发人员可以将需要执行的内容写在这个方法内。

44.13.3.1. 使用范围

stateless session bean、 message-driven bean、entity bean可以在定时器中登记,然后定时器在一定的时间点触发,记住:statefull session bean不能实现TimedObject接口。

44.13.3.2. 创建Timer

从context对象获取TimerService对象

TimerService timerService = context.getTimerService();
Timer timer = timerService.createTimer(intervalDuration,
  "created timer"); 

Timer是持久性的,假如应用服务器关机,当应用服务器重新启动时,Timer将被重新激活。

createTimer方法Date和long类型的参数表示到毫秒级的精度,但是Timer不是为实时系统提供的,所以它触发的精度可能不能达到精确的毫秒级,对于普通的应用程序,它的精度已经足够。

44.13.3.3. 定义Timer需要执行的内容

使用Timer的Bean必须实现javax.ejb.TimedObject接口,javax.ejb.TimedObject接口只有一个ejbTimeout()方法,该方法就是事件到期时触发的方法,需要把Timer需要执行的商业逻辑放在该方法面里。例如:

public class TimerSessionBean implements SessionBean, TimedObject {
    private SessionContext context;
    public TimerSessionBean() {
    }

    public void myCreateTimer(long intervalDuration) {
        System.out.println("TimerSessionBean: start createTimer ");
        TimerService timerService = context.getTimerService();
        Timer timer =
            timerService.createTimer(intervalDuration, "created timer");
    }
    public void ejbTimeout(Timer timer) {
        System.out.println("TimerSessionBean: ejbTimeout ");
    }
    public void setSessionContext(SessionContext sc) {
        System.out.println("TimerSessionBean: setSessionContext");
        context = sc;
    }
    public void ejbCreate() {
        System.out.println("TimerSessionBean: ejbCreate");
    }
    public void ejbRemove() {
    }
    public void ejbActivate() {
    }
    public void ejbPassivate() {
    }
}

44.13.3.4. 取消和保存Timer

Timer可以由以下几种方式取消:

  • 当一个单事件的Timer到期时,EJB容器调用完ejbTimeout方法后取消Timer

  • 当entity bean的实例被移除时,EJB容器取消和被移除实例相关的Timer

  • 当调用Timer的cancel方法时,EJB容器取消Timer

44.13.3.5. 获得Timer的信息

除了cancel 和 getHandle 方法之外,Timer接口还定义了一些其它方法来获得Timer的部分信息

public long getTimeRemaining();
public java.util.Date getNextTimeout();
public java.io.Serializable getInfo(); 

getInfo方法返回调用createTimer方法时最后一个参数的值。

44.13.3.6. Timer和交易

当一个 enterprise bean在交易的内部创建Timer,当交易回滚时,创建Timer的动作也同时回滚。

当一个 enterprise bean在交易的内部取消Timer,当交易回滚时,Timer取消的动作也同时被废除。