spring boot 應用-定時任務
阿新 • • 發佈:2022-03-06
之前寫過Oracle定時任務的指令碼,當時對於Windows server 伺服器是將指令碼新增到任務計劃中,但是 我就在實際中遇到過無法將指令碼新增到任務計劃中(試過了各種方法就是無法新增),這是我想到了是不是可以寫個定時任務來呼叫指令碼呢? 確實可以。原始碼地址 GitHub
2019年6月2日21:51更新(動態調整定時任務時間,之前的定時任務是寫死在註解上的,新修改為 呼叫h2表中的欄位)
spring boot 主程式中新增 @EnableScheduling
註解
使用 @Component
定義元件
在元件中使用 @Scheduled
定義定時任務
JavaRunBatApplication.java
package cn.geoary; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class JavaRunBatApplication { public static void main(String[] args) { SpringApplication.run(JavaRunBatApplication.class, args); } }
JavaRunBat.java
package cn.geoary.util; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; /** * @program: java-run-bat * @description: Java定時執行bat檔案 * @author: geoary * @create: 2019-05-06 14:41 **/ @Component public class JavaRunBat { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); /** * @description 建立定時任務 * @param * @return * @author geoary * @date 2019/5/6 */ // 每天1點執行 @Scheduled(cron = "0 0 1 * * ?") // 3分鐘執行一次 //@Scheduled(cron = "0 0/3 * * * ?") public void timingBat(){ runBat(); } /** * @description 執行bat檔案 * @param * @return * @author geoary * @date 2019/5/6 */ public static void runBat(){ String batPath = "E:/backup/data/autobackup.bat"; execBat(batPath); //execBat("1", batPath); } /** * @description 執行bat * @param * @return * @author geoary * @date 2019/5/6 */ public static void execBat(String ways, String batPath){ String cmdPre; switch (ways){ case "1": // 是執行完dir命令後關閉命令視窗 cmdPre = "cmd /c "; break; case "2": // 是執行完dir命令後不關閉命令視窗 cmdPre = "cmd /k "; break; case "3": // 會開啟一個新視窗後執行dir指令,原視窗會關閉 cmdPre = "cmd /c start "; break; default: // 會開啟一個新視窗後執行dir指令,原視窗不會關閉 cmdPre = "cmd /k start "; } String cmd = cmdPre + batPath; try{ Process ps = Runtime.getRuntime().exec(cmd); InputStream in = ps.getInputStream(); int c; while ((c = in.read()) != -1){ } in.close(); try { ps.waitFor(); }catch (Exception e){ e.printStackTrace(); } System.out.println("執行完成"+dateFormat.format(new Date())); }catch (Exception e){ e.printStackTrace(); } } public static void execBat(String batPath){ try{ Process ps = Runtime.getRuntime().exec("cmd /c start "+ batPath); InputStream in = ps.getInputStream(); int c; while ((c = in.read()) != -1){ } in.close(); try { ps.waitFor(); }catch (Exception e){ e.printStackTrace(); } System.out.println("執行完成"+dateFormat.format(new Date())); }catch (Exception e){ e.printStackTrace(); } } }
定時任務cron表示式:
表示式一般時這樣的:
每天凌晨1點執行 @Scheduled(cron = "0 0 1 * * ?")
每隔3分鐘執行 @Scheduled(cron = "0 0/3 * * * ?")
那麼這到底時怎麼寫出來的呢?
其實cron表示式後面一般有6個字元用空格分隔開,每一個域標識一個含義:
second
minuters
hours
dayOfMonth
month
dayOfWeek
序號 | 域 | 可出現的字元 |
---|---|---|
1 | second | , - * / 0到59的整數 |
2 | minuters | , - * / 0到59的整數 |
3 | hours | , - * / 0到23的整數 |
4 | dayOfMonth | , - * / ? L W C 0到31的整數 |
5 | month | , - * / 1到12的整數 |
6 | dayOfWeek | , - * / ? L #1到7的整數(或者SUN到SAT,1表示星期天,2表示星期一) |
序號 | 字元 | 含義 |
---|---|---|
1 | , | 表示列舉值 例如:在minuters域中使用2,10 表示在2分鐘和10分中各觸發一次 |
2 | - | 表示範圍 例如:在minuters 域中使用2-10 表示從2分鐘到10分鐘每分鐘出發一次 |
3 | * | 表示任意值 例如:在minuters域中使用* 則表示每分鐘都會觸發 |
4 | / | 表示 開始/步長 例如:在minuters域中使用2/10 表示從2分鐘開始 每個十分鐘觸發一次(2、12、22、32、42、52), 若開始值設定為*等效於0 |
5 | ? | 表示 不設定 通常出現在兩個相互影響的域中(dayOfMonth、dayOfWeek),當日期設定了那麼星期只能是? |
6 | L | 表示 最後值 例如:在日期中表示本月的最後一天 30號、31號、29號、28號;在星期中6L表示 本月最後一個星期五 |
7 | W | 表示有效工作日(及週一至週五) 只能出現在日期域中,系統將在離指定日期的最近的有效工作日觸發事件。例如: 5W,如果是星期六,則會在最近的工作日即星期五觸發即4號,如果5號是星期日,則會在下個星期一觸發即6號。注意,不會跨月 |
8 | # | 表示第幾個星期幾 只能用在星期中。例如: 4#2 表示某個月第2個星期三 |
示例:
cron表示式 | 含義 |
---|---|
0 0 10,14,16 * * ? | 每天上午10點,下午2點,4點 |
0 0/30 9-17 * * ? | 上午九點到下午5點間每30分鐘 |
0 0 12 ? * WED | 表示每個星期三中午12點 |
0 0 12 * * ? | 每天中午12點 |
0 15 10 ? * * | 每天上午10:15 |
0 15 10 * * ? 2005 | 2005年的每天上午10:15(一般不用帶年的) |
0 * 14 * * ? | 在每天下午2點到下午2:59期間的每1分鐘 |
0 0/5 14 * * ? | 在每天下午2點到下午2:59期間的每5分鐘 |
0 0/5 14,18 * * ? | 在每天下午2點到2:59期間和下午6點到6:59期間的每5分鐘 |
0 0-5 14 * * ? | 在每天下午2點到下午2:05期間的每1分鐘 |