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 表達式的值。