This tests the ejb3.1 annotation @Schedule.
The idea is to print the server time regularly, in a scheduled task method.
package com.jxee.ejb.test.singleton;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.apache.log4j.Logger;
/**
* Test jee 6 annotation @Schedule - automatic timers.
* <b>it's said that this annotation works with any EJBs except for
* Stateful session beans.</b>
* <br/>
* <br/>
* From the JEE6 API doc:
* <br/><br/>
* @Schedule schedules a timer for automatic creation with a timeout schedule
* based on a cron-like time expression. The annotated method is
* used as the timeout callback method.
* </li>
* <li>
* A timeout callback method can have public, private, protected,
* or package level access. The method must not be declared as final
* or static, and must not throw application exceptions.<br/>
* </li>
* <li>
* Schedule-based timer times are evaluated in the context of the
* default time zone associated with the container in which the
* application is executing. A schedule-based timer may optionally
* override this default and associate itself with a specific time zone.
* If the schedule-based timer is associated with a specific time zone,
* all its times are evaluated in the context of that time zone,
* regardless of the default time zone in which the container is executing.
* </li>
*/
//@Startup // eager initialization during the application startup sequence
@Singleton // a singleton scheduler, rather than a pool of schedulers...
public class ScheduleEJB {
private static final Logger log = Logger.getLogger(ScheduleEJB.class);
private String timeStr;
private Integer counter = 0;
@PostConstruct
public void init() {
log.debug(">>> inited: " + this.printInstance());
}
/**
* scheduled to execute on Thursday at every 20th second for every 3 minutes
*/
@Schedule(dayOfWeek="Thu", hour="*", minute="*/3", second="20", persistent=true)
public void printTime() {
doScheduledTask();
}
@Lock(LockType.WRITE)
private void doScheduledTask() {
++counter;
timeStr = "scheduled ["+ counter + "]" + ", timeStr(sec)=" + (new Date().getTime())/1000;
log.debug(this.timeStr);
}
@Lock(LockType.READ)
public String getTimeStr() {
return timeStr;
}
public String printInstance() {
return this.toString();
}
}
here's the screen shot of the server log:
小结:
1. @Schedule can apply to stateless session beans and message driven beans. but not stateful session beans.
2. @Schedule creates so called "automatic" timers to schedule tasks.
3. if you wanna make sure that the ejb is fully initialized before servicing, you can use the annotation @Startup
4. this example uses a singleton ejb to schedule the task. otherwise you end up with the scheduled method called by multiple times at the timer expires.
5. A timeout callback method can have public, private, protected, or package level access. The method must not be declared as final or static, and must not throw application exceptions.
6. Schedule-based timer times are evaluated in the context of the default time zone associated with the container in which the application is executing. A schedule-based timer may optionally override this default and associate itself with a specific time zone.
7. attribute "persistent" defaults to "true", meaning the timer/the scheduled task/method execution would survive server restart.
8. one thing to mention is that one might need to remove the "tmp/work/data" folders from JBoss6 server configuration, after a redeployment. otherwise, it won't work as expected - the singleton ejb looks like have multiple instances.