7

次の問題を解決するために必要な可能性を見つけようとしています。

a)「crontab構文」を使用してタスクをスケジュールするデータベーステーブルが必要な場合、構造は次のようになります。

    |-Id-|---Crontab 構文---|---------タスク----------|
    | | 1 | 30 * * * * * | MyClass.TaskA(引数[]) |
    | | 2 | 0 1 * * 1-5 * | MyClass.TaskB(引数[]) |
    | | | | | | | |

上記の表は、外部アプリケーションによっていつでも変更されます。追加または削除されたタスクは、スケジューラに即座に影響するはずです。

b) スケジューラ自体は、Java アプリケーション サーバー上に存在する必要があります。データベース テーブル内のアクティブなスケジュールされたタスクと常に同期する必要があります。スケジュール イベントが発生するたびに、'Task' の値を引数として EJB をトリガー/呼び出す必要があります。

上記の問題に対する答えを探しているわけではありません。むしろ、crontab の解析に使用できるフレームワークと、スケジューラを表す EJB をデプロイする方法についての入力です。

前もって感謝します。

4

3 に答える 3

28

EJB 3.1 @ScheduleAPI を参照してください。私たちが仕様のために選んだ API は、cron よりも Quartz の構文に少し近いもので、2 つの違いはわずかです。

注釈の例を次に示します。

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 と ScheduleExpression

  • @スケジュール
    • 静的に構成された
    • 多くのスケジュール方法が可能
    • 引数を渡すことができません
    • キャンセル不可

上記はすべてデプロイメント記述子で行われるため、事前に構成できるものに限定されます。より動的なバージョンでは、TimerService の次の署名を使用します。

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

  • スケジュール式
    • 動的に作成
    • ちょうど 1 つの @Timeout がすべての ScheduleExpression をサポートします
    • タイムアウト メソッドはjavax.ejb.Timerパラメータとして取る必要があります
    • 引数を渡すことができます
    • 呼び出し元または @Timeout メソッドでキャンセル可能

また、Bean のタイマー機能と@AroundTimeout同じように機能し、インターセプターが参加できるようにするインターセプター アノテーションがあることにも注意してください。@AroundInvoke

于 2011-09-09T18:31:56.373 に答える
0

EJB には独自のタイマーが組み込まれていますが、定型コードを記述して cron 解析を変換する必要があります。cron 命令自体の解析は簡単なはずです。

EJB の外に冒険することを恐れていないのであれば、レキシコアが述べたように、Quartz は優れたオプションです。

于 2011-09-09T12:59:15.557 に答える
-1

クォーツを見てください。Spring を使用する場合、非常に優れたサポートがあります。きちんとした、信頼できる良い仕事。

于 2011-09-09T12:53:21.473 に答える