ホームページ  >  記事  >  Java  >  Spring が Quartz を統合してスケジュールされたタスクのスケジューリングを実装する方法

Spring が Quartz を統合してスケジュールされたタスクのスケジューリングを実装する方法

高洛峰
高洛峰オリジナル
2017-02-07 15:19:251695ブラウズ

最近のプロジェクトでは、定期的にメンバーポイントを計算したり、サードパーティのインターフェースを呼び出したりするなど、スケジュールされた実行タスクを実装する必要があります。このプロジェクトでは Spring Framework を使用しているため、ここでは Spring Framework と合わせて紹介します。

次のように、通常のポジョであるジョブクラス

を作成します:

package com.pcmall.task;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class TaskA {
    private static Logger logger = LoggerFactory.getLogger(TaskA.class);
    public void taskA1(){
        for(int i=0;i<100;i++){
            System.out.println("----A1----" + i);
        }
    }
    public void taskA2(){
        for(int i=0;i<100;i++){
            System.out.println("----A2----" + i);
        }
    }
}

Spring構成ファイルに特定のタスクを設定します

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     
    <bean id="taskA" class="com.pcmall.task.TaskA"></bean>
    <bean id="taskB" class="com.pcmall.task.TaskB"></bean>
     
    <bean id="taskJobA1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="taskA"></property>
        <property name="targetMethod" value="taskA1"></property>
        <property name="concurrent" value="false"></property>
    </bean>
    <bean id="taskJobA2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="taskA"></property>
        <property name="targetMethod" value="taskA2"></property>
        <property name="concurrent" value="false"></property>
    </bean>
    <bean id="taskJobB1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="taskB"></property>
        <property name="targetMethod" value="taskB1"></property>
        <property name="concurrent" value="false"></property>
    </bean>
    <bean id="taskJobB2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="taskB"></property>
        <property name="targetMethod" value="taskB2"></property>
        <property name="concurrent" value="false"></property>
    </bean>
     
    <bean id="taskA1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="taskJobA1" />
        </property>
        <property name="cronExpression">
            <value>0 0/1 * * * ?</value>
        </property>
    </bean>
    <bean id="taskA2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="taskJobA2" />
        </property>
        <property name="cronExpression">
            <value>0 0/2 * * * ?</value>
        </property>
    </bean>
     
    <bean id="taskB1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="taskJobB1" />
        </property>
        <property name="cronExpression">
            <value>0 0/1 * * * ?</value>
        </property>
    </bean>
 
    <bean id="taskB2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="taskJobB2" />
        </property>
        <property name="cronExpression">
            <value>0 0/2 * * * ?</value>
        </property>
    </bean>
 
    <bean id="scheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="taskA1Trigger" />
                <ref bean="taskA2Trigger" />
                <ref bean="taskB1Trigger" />
                <ref bean="taskB2Trigger" />
            </list>
        </property>
    </bean>
</beans>

注意

トリガーは1つのジョブのみをトリガーできますが、ジョブが実行できる 複数のトリガーがトリガーされているため、同時実行の問題が発生します。 Quartz では、同じジョブを同時に実行したくない場合は、ジョブの代わりに StatefulJob を実装できます。 Spring で MethodInvokingJobDetailFactoryBean を使用する場合、concurrent="false" 属性を設定することでこれを実現できます。

終了ノート

Spring で個別のアプリケーションの代わりに Quartz を使用する利点は次のとおりです:

すべてのタスクのスケジュール設定を同じ場所に置くことで、タスクの保守が容易になります。

ジョブのエンコードのみ、トリガー、およびスケジューラは構成を通じて設定可能

Pojo Java Beanを使用して、ジョブインターフェースを実装せずにジョブを実行可能

Cron式の詳細な使用方法

フィールドで許可される値で許可される特殊文字

秒 0 ~ 59、 - * /
分 0 ~ 59、 - * /
時間 0 ~ 23、 - * /
日付 1 ~ 31、 - * / L W C
月 1 ~ 12 または 1 月 ~ 12 月、 - * /
週 1 ~ 7 または SUN ~ SAT、 - * ? / L C #
年 (オプション) 空白のまま、1970 ~ 2099、 - * /

例:

0/5 * * * * : 毎に実行5 秒

「」文字はすべての値を指定するために使用されます。例: 「」は、分フィールドの「毎分」を意味します。

「?」文字は日付フィールドと曜日フィールドでのみ使用されます。 「非明示的な値」を指定するために使用されます。これは、これら 2 つのフィールドのいずれかに何かを指定する必要がある場合に便利です。以下の例を見れば理解できるでしょう。

日と曜日の 2 つの要素は相互に排他的です。そのフィールドを設定しないことを示すには、疑問符を設定する必要があります。

「-」文字は範囲を指定するために使用されます。たとえば、時間領域の「10-12」は、「10 時、11 時、12 時」を意味します。

「,」文字は追加の値を指定するために使用されます。例: 「MON, WED, FRI」は、曜日フィールドの「月曜日、水曜日、金曜日」を意味します。

「/」文字は増分を指定するために使用されます。例: 秒フィールドの「0/15」は、1 分あたり 0、15、30、45 秒を意味します。分のフィールドの「5/15」は、各時間の 5、20、35、50 を意味します。 「/」の前の記号「」 (/10 など) は、「/」の前の 0 (0/10 など) と同等です。本質を覚えておいてください。式の各数値フィールドは最大値と最小値のセットです。たとえば、秒フィールドと分のフィールドのセットは 0 ~ 59、日付フィールドは 1 ~ 31、月フィールドは 1- です。 12.文字「/」は、各文字フィールドで対応する値を取得するのに役立ちます。例: 「7/6」が月フィールドにある場合、毎年 6 月ではなく、7 月にのみトリガーされます。

L は「last」の略語で、月の日フィールドと曜日フィールドを表すことができますが、2 つのフィールドの意味は異なります。たとえば、月の日フィールドは月の最終日を表します。月。曜日フィールドが「7」または「SAT」を表す場合、曜日フィールドの前に数字が追加されると、その月の最後の数日を表します。たとえば、「6L」は月の最後の数日を表します。月末の金曜日。

文字「W」は日付フィールドにのみ使用できます。この文字は、日付に最も近い営業日を指定するために使用されます。例: 日付フィールドに「15W」と入力すると、今月の 15 日の最も近い営業日を意味します。したがって、15 日が土曜日の場合、タスクは 14 日にトリガーされます。 15 日が日曜日の場合、タスクは 16 日の月曜日にトリガーされます。日付フィールドに「1W」を入力すると、1 日が土曜日であっても、タスクは次の月曜日 (3 日) にのみトリガーされます。「W」文字で指定された最新の稼働日をまたぐことはできません。数か月。文字「W」は単一の値でのみ使用でき、数値フィールドには使用できません。たとえば、1-15W は誤りです。

「L」と「W」は日付フィールドで併用できます。LW は今月の最終週の営業日を表します。

文字「#」は曜日フィールドにのみ使用できます。この文字は、月の特定の日を指定するために使用されます。例: 「6#3」は今月の第 3 週の金曜日を意味します (6 は金曜日、3 は第 3 週を意味します)。 「2#1」は、月の第 1 週の月曜日を意味します。 「4#5」は第5週の水曜日を意味します。

文字「C」は日付フィールドと曜日フィールドに表示できます。この文字は、指定された「カレンダー」に依存します。つまり、この式の値は、関連する「カレンダー」の計算結果に依存します。関連付けられている「カレンダー」がない場合は、含まれるすべての「カレンダー」と同等になります。たとえば、日付フィールドが「5C」の場合、関連付けられた「カレンダー」の最初の日、または今月の最初の日から 5 日後を意味します。週フィールドが「1C」の場合、関連する「カレンダー」の最初の日、または週の最初の日の翌日、つまり日曜日(月曜日)の翌日を意味します。

式の例

"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

上記の Spring を統合してスケジュールされたタスクのスケジューリングを実装する方法は、エディターによって共有されたすべての内容です。参考になれば幸いです。また、PHP 中国語 Web サイトをサポートしていただければ幸いです。

Spring が Quartz を統合してスケジュールされたタスクのスケジューリングを実装する方法に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。