使用“crontab语法”进行EJB调度任务

我试图找出解决以下问题的可能性。

a)我想有一个使用“crontab语法”来安排任务的数据库表,结构将是这样的:

     | -Id- | --- Crontab语法--- | ---------任务---------- |
     |  1 |  30 * * * * * |  MyClass.TaskA(args [])|
     |  2 |  0 1 * * 1-5 * |  MyClass.TaskB(args [])|
     |  |  |  |

上表将由外部应用程序随时修改。 添加或删除的任务应立即影响调度程序。

b)调度程序本身应驻留在Java应用程序服务器上。 它应该不断与数据库表中的活动计划任务同步。 每当调度事件发生时,它应该触发/调用EJB,并将’Task’中的值作为参数。

我不是在寻找上述问题的答案。 但是,在哪些框架中可以使用crontab解析的一些输入以及应该以何种方式部署表示调度程序的EJB。

提前致谢。

请参阅EJB 3.1 @Schedule API。 我们为规范选择的API比cron更接近Quartz语法 – 两者之间的微小差异。

这是一个注释示例:

 package org.superbiz.corn; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Schedule; import javax.ejb.Schedules; import javax.ejb.Singleton; import java.util.concurrent.atomic.AtomicInteger; /** * This is where we schedule all of Farmer Brown's corn jobs */ @Singleton @Lock(LockType.READ) // allows timers to execute in parallel public class FarmerBrown { private final AtomicInteger checks = new AtomicInteger(); @Schedules({ @Schedule(month = "5", dayOfMonth = "20-Last", minute = "0", hour = "8"), @Schedule(month = "6", dayOfMonth = "1-10", minute = "0", hour = "8") }) private void plantTheCorn() { // Dig out the planter!!! } @Schedules({ @Schedule(month = "9", dayOfMonth = "20-Last", minute = "0", hour = "8"), @Schedule(month = "10", dayOfMonth = "1-10", minute = "0", hour = "8") }) private void harvestTheCorn() { // Dig out the combine!!! } @Schedule(second = "*", minute = "*", hour = "*") private void checkOnTheDaughters() { checks.incrementAndGet(); } public int getChecks() { return checks.get(); } } 

这里有完整的来源

您可以通过ScheduleExpression类以编程方式执行相同的操作,该类只是上述注释的可构造版本。 如果计划在代码中完成,上面的例子就是这样:

 package org.superbiz.corn; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.ScheduleExpression; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.ejb.Timeout; import javax.ejb.Timer; import javax.ejb.TimerConfig; import javax.ejb.TimerService; import java.util.concurrent.atomic.AtomicInteger; /** * This is where we schedule all of Farmer Brown's corn jobs * * @version $Revision$ $Date$ */ @Singleton @Lock(LockType.READ) // allows timers to execute in parallel @Startup public class FarmerBrown { private final AtomicInteger checks = new AtomicInteger(); @Resource private TimerService timerService; @PostConstruct private void construct() { final TimerConfig plantTheCorn = new TimerConfig("plantTheCorn", false); timerService.createCalendarTimer(new ScheduleExpression().month(5).dayOfMonth("20-Last").minute(0).hour(8), plantTheCorn); timerService.createCalendarTimer(new ScheduleExpression().month(6).dayOfMonth("1-10").minute(0).hour(8), plantTheCorn); final TimerConfig harvestTheCorn = new TimerConfig("harvestTheCorn", false); timerService.createCalendarTimer(new ScheduleExpression().month(9).dayOfMonth("20-Last").minute(0).hour(8), harvestTheCorn); timerService.createCalendarTimer(new ScheduleExpression().month(10).dayOfMonth("1-10").minute(0).hour(8), harvestTheCorn); final TimerConfig checkOnTheDaughters = new TimerConfig("checkOnTheDaughters", false); timerService.createCalendarTimer(new ScheduleExpression().second("*").minute("*").hour("*"), checkOnTheDaughters); } @Timeout public void timeout(Timer timer) { if ("plantTheCorn".equals(timer.getInfo())) { plantTheCorn(); } else if ("harvestTheCorn".equals(timer.getInfo())) { harvestTheCorn(); } else if ("checkOnTheDaughters".equals(timer.getInfo())) { checkOnTheDaughters(); } } private void plantTheCorn() { // Dig out the planter!!! } private void harvestTheCorn() { // Dig out the combine!!! } private void checkOnTheDaughters() { checks.incrementAndGet(); } public int getChecks() { return checks.get(); } } 

这个例子的来源就在这里

注意,这两个示例都可以在普通IDE中运行,并且具有使用EJB 3.1中新增的Embeddable EJBContainer API的测试用例。

@Schedule vs ScheduleExpression

  • @时间表
    • 静态配置
    • 许多计划方法都是可能的
    • 无法传递参数
    • 无法取消

以上都是在部署描述符中完成的,因此仅限于可以预先配置的内容。 更动态的版本使用TimerService的以下签名:

TimerService.createCalendarTimer(javax.ejb.ScheduleExpression,javax.ejb.TimerConfig)

  • ScheduleExpression
    • 动态创建
    • 正好一个@Timeout支持所有ScheduleExpression
    • timeout方法必须将javax.ejb.Timer作为参数
    • 参数可以通过
      • 调用者在TimerConfig.setInfo(Serializable)对象中包装参数
      • @Timeout方法通过Timer.getInfo()访问它们
    • 可以被调用者或@Timeout方法取消

另请注意,有一个拦截器@AroundTimeout注释,其function与@AroundInvoke相同,并允许拦截器参与bean的计时器function。

EJB有自己的内置定时器 ,但你必须编写样板代码来翻译cron解析。 解析cron指令本身应该是微不足道的。

如果你不害怕在EJB之外冒险,那么Quartz就像lexicore一样提到了一个很好的选择。

看看Quartz吧 。 如果你使用Spring,那里有非常好的支持。 一个整洁,可靠的好工作的东西。