具有“crontab语法”的EJB调度任务 [英] Have an EJB schedule tasks with "crontab syntax"

查看:106
本文介绍了具有“crontab语法”的EJB调度任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



a)我想有一个使用crontab语法的数据库表,计划任务,结构将是这样的:

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

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



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



我不是在寻找上述问题的答案。但是在某些框架中可以使用什么框架来进行crontab解析以及EJB表示调度程序的方式。



提前感谢

解决方案

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



这是一个注释示例:

  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;

/ **
*这是我们安排所有Farmer Brown的玉米作业的地方
* /
@Singleton
@Lock(LockType.READ) //允许定时器并行执行
public class FarmerBrown {

private final AtomicInteger checking = 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(){
/ /挖出种植者!!!
}

@Schedules({
@Schedule(month =9,dayOfMonth =20-Last,minute =0,hour =8 ,
@Schedule(month =10,dayOfMonth =1-10,minute =0,hour =8)
})
private void harvestTheCorn()
//挖出组合!
}

@Schedule(second =*,minute =*,hour =*)
private void checkOnTheDaughters(){
checks。 incrementAndGet();
}

public int getChecks(){
return checks.get();
}
}

这个 here



您可以通过编程方式通过 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;

/ **
*这是我们安排所有农民布朗的玉米工作的地方
*
* @version $修订$ $日期$
* /
@Singleton
@Lock(LockType.READ)//允许定时器并行执行
@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(){
//挖出种植者!
}

private void harvestTheCorn(){
//挖出组合!
}

private void checkOnTheDaughters(){
checks.incrementAndGet();
}

public int getChecks(){
return checks.get();
}
}

此示例的源代码是这里



旁注,两个例子都是可以在普通IDE中运行,并且具有使用Embeddable的测试用例 EJBContainer API在EJB 3.1中也是新的。



@Schedule与ScheduleExpression




  • @Schedule

    • 静态配置

    • 可以使用许多计划方法

    • 无法传递参数

    • 无法取消




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



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




  • ScheduleExpression



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


I am trying to figure out the possibilities I have to solve the following problem.

a) I want to have a database table that uses "crontab syntax" to schedule tasks, the structure would be something like this:

    |-Id-|---Crontab Syntax---|---------Task----------|
    | 1  | 30 *  *  *  *    * | MyClass.TaskA(args[]) |
    | 2  | 0  1  *  *  1-5  * | MyClass.TaskB(args[]) |
    |    |                    |                       |

The above table will be modified at any time by an external application. Tasks added or removed should instantly affect the scheduler.

b) The scheduler itself should reside on a Java application server. It should constantly be synched with the active scheduled tasks in the database table. Whenever a schedule event occurs it should trigger/call an EJB with the value in 'Task' as argument.

I am not looking for an answer to the above problem. But rather some input in what frameworks can be used for the crontab parsing and in what manner the EJB representing the scheduler should be deployed.

Thanks in advance.

解决方案

See the EJB 3.1 @Schedule API. The API we chose for the spec is a little closer to Quartz syntax than cron -- tiny variances between the two.

Here's an annotation example:

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();
    }
}

Full source for this here

You can do the same thing programmatically via the ScheduleExpression class which is just a constructable version of the above annotation. Here's what the above example would look like if the schedule was done in code:

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();
    }
}

The source for this example is here

Side note, both examples are runnable in a plain IDE and have test cases that use the Embeddable EJBContainer API also new in EJB 3.1.

@Schedule vs ScheduleExpression

  • @Schedule
    • Statically configured
    • Many schedule methods are possible
    • Not possible to pass arguments
    • Cannot be cancelled

The above is all done in the deployment descriptor and is therefore limited to only things that can be configured in advance. The more dynamic version uses the following signature of the TimerService:

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

  • ScheduleExpression
    • Dynamically created
    • Exactly one @Timeout supports all ScheduleExpression
    • The timeout method must take javax.ejb.Timer as a parameter
    • Arguments can be passed
    • Can be cancelled by the caller or the @Timeout method

Also note that there is an interceptor @AroundTimeout annotation that functions identically to @AroundInvoke and allows interceptors to participate in the bean's timer functionality.

这篇关于具有“crontab语法”的EJB调度任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆