web-dev-qa-db-ja.com

Springでスケジュールされたタスクにアクセスする

Springのタスクスケジューラ:内にいくつかのタスクがスケジュールされています。

<task:scheduled-tasks>
    <task:scheduled ref="task1" method="run"
        cron="0 0 */0 * * *" />
    <task:scheduled ref="task2" method="run"
        cron="0 0 */30 * * *" />
</task:scheduled-tasks>

<task:scheduler id="scheduler" pool-size="10" />

アプリケーションコンテキスト内からスケジュールされたタスクのリストにアクセスしてメタ情報(次の実行時間など)を取得するにはどうすればよいですか?

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
ThreadPoolTaskScheduler scheduler = (ThreadPoolTaskScheduler)context.getBean("scheduler");
//... how to continue from here?
15
achingfingers

これを行うためのパブリックAPIはSpringにはありません。

関連:

私はこれを理解しました

これから始めて、スケジュールを取得します。

    ThreadPoolTaskScheduler xScheduler = (ThreadPoolTaskScheduler)this.taskScheduler;

    ScheduledThreadPoolExecutor xService = (ScheduledThreadPoolExecutor)xScheduler.getScheduledExecutor();

    BlockingQueue<Runnable> queue = xService.getQueue();
    Object[] scheduledJobs = queue.toArray();

この配列がデバッガーのインスタンスを調べて、必要なものを見つける場合。

次に、このようなリフレクションコードを記述して、SpringとJavaの非表示のAPIを取得します。アクセシブルセットを参照してください。これは、これらのプライベートアイテムを取得する唯一の方法です。特定のプライベートフィールドを取得し、APIドキュメントを確認し、Eclipseでこれらのクラスのソースを表示するには、さまざまなパブリッククラスを使用する必要がある場合があります。

            Method delayM = obj.getClass().getDeclaredMethod("getDelay", TimeUnit.class);
            delayM.setAccessible(true);
            // delayM = obj.getClass().getDeclaredMethod("getDelay", TimeUnit.class);
            Long delay = (Long)delayM.invoke(obj, new Object[] { tu } );

トリガーとルートランナブルは、このオブジェクトの呼び出し可能フィールドにあります。パブリッククラスではないReschedulingRunnableのインスタンスで、Springになぜこれを行ったのかを尋ねます。リフレクションを使用して、DelegatingErrorHandlingRunnableからデリゲートを取得できます。

3
Randy Poznan