動態控制 Spring Boot 中的 @Scheduled 定時任務

1. 概論

Spring Boot 中的 @Scheduled 註解爲定時任務提供了一種很簡單的實現,只須要在註解中加上一些屬性,例如 fixedRate、fixedDelay、cron(最經常使用)等等,而且在啓動類上面加上 @EnableScheduling 註解,就能夠啓動一個定時任務了。java

可是在某些狀況下,並無這麼簡單,例如項目部署上線以後,咱們可能會修改定時任務的執行時間,而且中止、重啓定時任務等,由於定時任務是直接寫死在程序中的,修改起來不是很是的方便。因此,簡單記錄一下本身的一些解決方案,僅供參考。segmentfault

2. 在配置文件中設置參數

以 cron 表達式爲例,通常的作法是將 @Scheduled 的屬性寫在程序中的,例如這樣:app

@Component
public class TestTask {
    private static SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(cron = "0/5 * * * * ?")
    public void test(){
        System.out.println(dateFmt.format(new Date()) + " : 執行定時任務");
    }
}

若是須要修改的話,咱們能夠將 cron 表達式配在 application.yml 中:ide

#application.yml中的配置
scheduled:
  cron: 0/5 * * * * ?

而後在 @Scheduled 中獲取這個配置:code

@Scheduled(cron = "${scheduled.cron}")
public void test(){
    System.out.println(dateFmt.format(new Date()) + " : 執行定時任務");
}

等到了線上的時候,再經過修改配置文件中的內容來進行控制。具體怎麼動態的修改配置文件中的內容,後面我會專門寫一篇文章來講明。orm

3. 如何關閉定時任務

一種方式是根據實際的需求,設置一個好久以後的時間再執行,例如明年的某個時間點,你可能會想何不設置一個已通過去的時間(例如 2012 年),可是很遺憾,@Scheduled 並不支持設置年份。部署

另外 Spring Boot 2.1 以上的版本還提供了一種中止定時任務的方案,就是在 cron 中配置 "-" 便可,你也能夠在配置文件中設置這個符號:get

#application.yml中的配置
scheduled:
  cron: "-"

注意這裏必須加上一個雙引號,由於在 application.yml 中, - 是一個特殊的字符。it

4. 爲定時任務設置開關

若是嫌上面這種方式比較死板,能夠嘗試另外一種,給定時任務加上開關的方案,在配置文件中配置一個 boolean 屬性,若是是 true 的話,就開啓定時任務,不然不開啓。io

#application.yml中的配置
scheduled:
  cron: 0/5 * * * * ?
enable:
  scheduled: true

而後咱們可使前面說到的 @Conditional 註解來實現這個功能,若是你還不瞭解,能夠看我這篇文章:淺談 Spring Boot 中的 @Conditional 註解

其實 @Scheduled 註解,是被一個叫作 ScheduledAnnotationBeanPostProcessor 的類所攔截的,因此咱們能夠根據配置,決定是否建立這個 bean,若是沒有這個 bean,@Scheduled 就不會被攔截,那麼定時任務確定不會執行了,有了這個思路,實現起來就很簡單了。須要注意的是:這種方式,啓動類上面的 @EnableScheduling 須要去掉。

而後建立一個 ScheduledCondtion 類,內容以下:

public class ScheduledCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //讀取配置中的屬性
        return Boolean.valueOf(context.getEnvironment().getProperty("enable.scheduled"));
    }
}

這個類的功能很簡單,就是去讀取配置,而後返回一個 boolean 值。

而後建立一個配置類 ScheduledConfig ,內容以下:

@Configuration
public class ScheduledConfig {

    @Conditional(ScheduledCondition.class)
    @Bean
    public ScheduledAnnotationBeanPostProcessor processor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }
}

這個配置,就是以 ScheduledCondtion 爲條件,決定是否建立 bean。而後,啓動項目,定時任務就會執行,若是咱們將配置修改成 false,則不會執行。

這樣的話,咱們就可以很容易的啓動或者關閉定時任務了,而且也能夠實時修改 cron 表達式的值。

相關文章
相關標籤/搜索