1. 程式人生 > >SpringBoot學習-(十九)SpringBoot定時器#Schedule

SpringBoot學習-(十九)SpringBoot定時器#Schedule

定時器概述

後臺專案開發中經常會用到定時器,現在實現定時器的方式也是多種多樣。下面列舉幾種常見的定時器實現方式:

  1. Quartz:Quartz的使用相當廣泛,它是一個功能強大的排程器,當然使用起來也相對麻煩;
  2. java.util包裡的Timer,它也可以實現定時任務但是功能過於單一所有使用很少。
  3. 就是我們今天要介紹的Spring自帶的定時任務Schedule,其實可以把它看作是一個簡化版的,輕量級的Quartz,使用起來也相對方便很多。

使用步驟

  1. 配置Schedule
  2. 書寫定時器類

配置Schedule

package com.ahut.config;

import
org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; /** * * @ClassName: ScheduleConfig * @Description: 配置定時器 * @author cheng * @date 2017年10月16日 上午10:25:16 */ @Configuration @EnableScheduling public class ScheduleConfig { }

書寫定時器類

package com.ahut.schedule;

import java.text.MessageFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 
 * @ClassName: ScheduledTasks
 * @Description: 自定義定時器任務
 * @author
cheng * @date 2017年10月16日 上午10:07:03 */
@Component public class ScheduledTasks { // 日誌 private Logger log = LoggerFactory.getLogger(this.getClass()); private int fixedDelayCount = 1; /** * * @Title: testFixDelay * @Description:表示上一次任務執行完成後多久再次執行,引數型別為long,單位ms; */ @Scheduled(fixedDelay = 5000) public void testFixDelay() { log.info(MessageFormat.format("fixedDelay()第{0}次執行", fixedDelayCount++)); } }

執行結果:

2017-10-16 17:07:36.911 logback [MessageBroker-1] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第1次執行
2017-10-16 17:07:36.918 logback [restartedMain] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
2017-10-16 17:07:36.940 logback [restartedMain] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
2017-10-16 17:07:36.963 logback [restartedMain] INFO  o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2017-10-16 17:07:37.005 logback [restartedMain] INFO  o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8080 (http)
2017-10-16 17:07:37.034 logback [restartedMain] INFO  com.ahut.AhutApplication - Started AhutApplication in 8.228 seconds (JVM running for 9.71)
2017-10-16 17:07:41.912 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第2次執行
2017-10-16 17:07:46.914 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第3次執行
2017-10-16 17:07:51.915 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第4次執行
2017-10-16 17:07:56.920 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第5次執行
2017-10-16 17:08:01.923 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第6次執行
2017-10-16 17:08:06.924 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第7次執行
2017-10-16 17:08:11.926 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第8次執行
2017-10-16 17:08:16.928 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第9次執行
2017-10-16 17:08:21.928 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedDelay()第10次執行

方法:

    private int fixedRateCount = 1;

    /**
     * 
     * @Title: testFixedRate
     * @Description:fixedRate = 5000表示當前方法開始執行5000ms後,Spring scheduling會再次呼叫該方法
     */
    @Scheduled(fixedRate = 5000)
    public void testFixedRate() {
        log.info(MessageFormat.format("fixedRate: 第{0}次執行方法", fixedRateCount++));
    }

執行結果:

2017-10-16 17:10:41.629 logback [MessageBroker-1] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第1次執行方法
2017-10-16 17:10:41.636 logback [restartedMain] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
2017-10-16 17:10:41.655 logback [restartedMain] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
2017-10-16 17:10:41.685 logback [restartedMain] INFO  o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2017-10-16 17:10:41.720 logback [restartedMain] INFO  o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8080 (http)
2017-10-16 17:10:41.729 logback [restartedMain] INFO  com.ahut.AhutApplication - Started AhutApplication in 6.266 seconds (JVM running for 7.315)
2017-10-16 17:10:46.628 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第2次執行方法
2017-10-16 17:10:51.629 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第3次執行方法
2017-10-16 17:10:56.629 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第4次執行方法
2017-10-16 17:11:01.629 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第5次執行方法
2017-10-16 17:11:06.630 logback [MessageBroker-4] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第6次執行方法
2017-10-16 17:11:11.631 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第7次執行方法
2017-10-16 17:11:16.630 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第8次執行方法
2017-10-16 17:11:21.631 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - fixedRate: 第9次執行方法

方法:

    private int initialDelayCount = 1;

    /**
     * 
     * @Title: testInitialDelay
     * @Description:initialDelay =1000表示延遲1000ms執行第一次任務
     */
    @Scheduled(initialDelay = 1000, fixedRate = 5000)
    public void testInitialDelay() {
        log.info(MessageFormat.format("initialDelay: 第{0}次執行方法", initialDelayCount++));
    }

執行結果:

2017-10-16 17:44:11.217 logback [MessageBroker-1] INFO  com.ahut.schedule.ScheduledTasks - initialDelay: 第1次執行方法
2017-10-16 17:44:16.216 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - initialDelay: 第2次執行方法
2017-10-16 17:44:21.217 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - initialDelay: 第3次執行方法
2017-10-16 17:44:26.217 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - initialDelay: 第4次執行方法
2017-10-16 17:44:31.217 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - initialDelay: 第5次執行方法

方法:

    private int cronCount = 1;

    /**
     * 
     * @Title: testCron
     * @Description:cron接受cron表示式,根據cron表示式確定定時規則
     */
    @Scheduled(cron = "*/6 * * * * ?")
    public void testCron() {
        log.info(MessageFormat.format("core: 第{0}次執行方法", cronCount++));
    }

執行結果:

2017-10-16 17:47:06.009 logback [MessageBroker-1] INFO  com.ahut.schedule.ScheduledTasks - core: 第1次執行方法
2017-10-16 17:47:12.007 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - core: 第2次執行方法
2017-10-16 17:47:18.001 logback [MessageBroker-3] INFO  com.ahut.schedule.ScheduledTasks - core: 第3次執行方法
2017-10-16 17:47:24.001 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - core: 第4次執行方法
2017-10-16 17:47:30.002 logback [MessageBroker-2] INFO  com.ahut.schedule.ScheduledTasks - core: 第5次執行方法

分析

@Scheduled 註解原始碼如下

/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.scheduling.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * An annotation that marks a method to be scheduled. Exactly one of
 * the {@link #cron()}, {@link #fixedDelay()}, or {@link #fixedRate()}
 * attributes must be specified.
 *
 * <p>The annotated method must expect no arguments. It will typically have
 * a {@code void} return type; if not, the returned value will be ignored
 * when called through the scheduler.
 *
 * <p>Processing of {@code @Scheduled} annotations is performed by
 * registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
 * done manually or, more conveniently, through the {@code <task:annotation-driven/>}
 * element or @{@link EnableScheduling} annotation.
 *
 * <p>This annotation may be used as a <em>meta-annotation</em> to create custom
 * <em>composed annotations</em> with attribute overrides.
 *
 * @author Mark Fisher
 * @author Dave Syer
 * @author Chris Beams
 * @since 3.0
 * @see EnableScheduling
 * @see ScheduledAnnotationBeanPostProcessor
 * @see Schedules
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {

    /**
     * A cron-like expression, extending the usual UN*X definition to include
     * triggers on the second as well as minute, hour, day of month, month
     * and day of week.  e.g. {@code "0 * * * * MON-FRI"} means once per minute on
     * weekdays (at the top of the minute - the 0th second).
     * @return an expression that can be parsed to a cron schedule
     * @see org.springframework.scheduling.support.CronSequenceGenerator
     */
    String cron() default "";

    /**
     * A time zone for which the cron expression will be resolved. By default, this
     * attribute is the empty String (i.e. the server's local time zone will be used).
     * @return a zone id accepted by {@link java.util.TimeZone#getTimeZone(String)},
     * or an empty String to indicate the server's default time zone
     * @since 4.0
     * @see org.springframework.scheduling.support.CronTrigger#CronTrigger(String, java.util.TimeZone)
     * @see java.util.TimeZone
     */
    String zone() default "";

    /**
     * Execute the annotated method with a fixed period in milliseconds between the
     * end of the last invocation and the start of the next.
     * @return the delay in milliseconds
     */
    long fixedDelay() default -1;

    /**
     * Execute the annotated method with a fixed period in milliseconds between the
     * end of the last invocation and the start of the next.
     * @return the delay in milliseconds as a String value, e.g. a placeholder
     * @since 3.2.2
     */
    String fixedDelayString() default "";

    /**
     * Execute the annotated method with a fixed period in milliseconds between
     * invocations.
     * @return the period in milliseconds
     */
    long fixedRate() default -1;

    /**
     * Execute the annotated method with a fixed period in milliseconds between
     * invocations.
     * @return the period in milliseconds as a String value, e.g. a placeholder
     * @since 3.2.2
     */
    String fixedRateString() default "";

    /**
     * Number of milliseconds to delay before the first execution of a
     * {@link #fixedRate()} or {@link #fixedDelay()} task.
     * @return the initial delay in milliseconds
     * @since 3.2
     */
    long initialDelay() default -1;

    /**
     * Number of milliseconds to delay before the first execution of a
     * {@link #fixedRate()} or {@link #fixedDelay()} task.
     * @return the initial delay in milliseconds as a String value, e.g. a placeholder
     * @since 3.2.2
     */
    String initialDelayString() default "";

}
  • cron:cron表示式,指定任務在特定時間執行;
  • fixedDelay:表示上一次任務執行完成後多久再次執行,引數型別為long,單位ms;
  • fixedDelayString:與fixedDelay含義一樣,只是引數型別變為String;
  • fixedRate:表示按一定的頻率執行任務,引數型別為long,單位ms;
  • fixedRateString: 與fixedRate的含義一樣,只是將引數型別變為String;
  • initialDelay:表示延遲多久再第一次執行任務,引數型別為long,單位ms;
  • initialDelayString:與initialDelay的含義一樣,只是將引數型別變為String;
  • zone:時區,預設為當前時區,一般沒有用到。