1. 程式人生 > >Spring自帶定時器實現定時任務

Spring自帶定時器實現定時任務

str esc exec count nis 開始 針對 exe 結束

在Spring框架中實現定時任務的辦法至少有2種(不包括Java原生的Timer及Executor實現方式),一種是集成第三方定時任務框架,如無處不在的Quartz;另一種便是Spring自帶的定時器(僅針對3.0之後的版本)。本文將圍繞Spring自帶定時器,模擬實現一個最簡單的定時任務,看看使用起來到底有多簡單。

  1. 第二步,啟動Schedule配置,XML方式的配置請自行搜索,本文僅針對註解方式的實現提供說明。

@EnableScheduling

@EnableScheduling註解,用來引入Schedule的相關配置,從其源碼可見一斑。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}

而SchedulingConfiguration的關鍵,則是定義ScheduledAnnotationBeanPostProcessor。顧名思義,針對基於註解的Bean組件,進行Scheduled處理。

  1. 第二步,在需要定時執行的方法上添加註解
    @Scheduled(fixedDelay = 5000L)
    @Scheduled(fixedRate = 5000L)
    @Scheduled(cron = "xxx")

閱讀Scheduled源碼,

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String cron() default "";
    String zone() default "";
    long fixedDelay() default -1L;
    String fixedDelayString() default "";
    long fixedRate() default -1L;
    String fixedRateString() default "";
    long initialDelay() default -1L;
    String initialDelayString() default "";
}

發現這個註解的Target,僅適用於方法和其他註解類型,可重復。參數包括zone - 時區,fixedRate-固定啟動頻率(單位毫秒),fixedDelay-固定執行周期(單位毫秒),cron-自定義Cron表達式。

fixedRate和fixedDelay的區別很簡單,一個是開始時間按照一個固定的頻率執行,不管之前的有沒有結束,另一個從上一個任務結束到下一個任務的開始,按照固定的時間間隔。寫個簡單的sample看下效果:

@Component
public class SpringTaskDemo {

    private int round = 0;

    @Scheduled(fixedRate = 5000L)
    public void counting(){
        round++;
        System.out.println(">>>>>>>>>" + "Counting Round " + round);
        System.out.println("Start at : " + new DateFormatter("yyyy-MM-dd HH:mm:sss").print(new Date(), Locale.CHINESE));
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Finish at: "+ new DateFormatter("yyyy-MM-dd HH:mm:sss").print(new Date(), Locale.CHINESE));
    }
}

fixedRate 效果如下:

>>>>>>>>>Counting Round 1
Start at : 2018-09-03 00:28:023
Finish at: 2018-09-03 00:28:026
>>>>>>>>>Counting Round 2
Start at : 2018-09-03 00:28:028
Finish at: 2018-09-03 00:28:031
>>>>>>>>>Counting Round 3
Start at : 2018-09-03 00:28:033
Finish at: 2018-09-03 00:28:036
>>>>>>>>>Counting Round 4
Start at : 2018-09-03 00:28:038
Finish at: 2018-09-03 00:28:041
>>>>>>>>>Counting Round 5
Start at : 2018-09-03 00:28:043
Finish at: 2018-09-03 00:28:046

fixedDelay效果如下:

>>>>>>>>>Counting Round 1
Start at : 2018-09-03 00:30:031
Finish at: 2018-09-03 00:30:034
>>>>>>>>>Counting Round 2
Start at : 2018-09-03 00:30:039
Finish at: 2018-09-03 00:30:042
>>>>>>>>>Counting Round 3
Start at : 2018-09-03 00:30:047
Finish at: 2018-09-03 00:30:050
>>>>>>>>>Counting Round 4
Start at : 2018-09-03 00:30:055
Finish at: 2018-09-03 00:30:058
>>>>>>>>>Counting Round 5
Start at : 2018-09-03 00:31:003
Finish at: 2018-09-03 00:31:006

這麽看起來,其自帶的定時任務,還是很準時的。cron表達式支持定義更為復雜的任務周期,關於cron的例子不再枚舉,請自行搜索並測試。

Spring自帶定時器實現定時任務