cron4j是Java平台的一個調度器,使用cron4j你只需要制定一些簡單的規則,就可以在規定好的時間內執行你所指定的任務。本篇我們主要介紹cron4j在JFinal中的使用。
cron4j基本概念
主要步驟:
cron4j的主要對象為scheduler(調度器)。
1. 我們在使用的時候需要先new一個scheduler實例。
2. 通過schedule方法添加實現了java.lang.Runnable
接口的實例對象作為要調度的任務(或是用cron4j提供的it.sauronsoftware.con4j.Task
類來實例一個對象)。
3. 用一個時間字符串來代表指定的scheduling pattern(調度模式)指定任務在何時執行(或是使用一個it.sauronsoftware.cron4j.SchedulingPattern類的實例)。
4. 最后啟動scheduler。
- 調度器可以安排任意數量的任務。
- 可以在調度器運行的過程中,添加新的任務或是對已經在運行的任務進行修改、移除。\
- 調度器可以開啟或停止任意次。
下載
maven:
<dependency>
<groupId>it.sauronsoftware.cron4j</groupId>
<artifactId>cron4j</artifactId>
<version>2.2.5</version>
<scope>provided</scope>
</dependency>
開始使用
新建JobBean
JobBean:
package utils;
public class JobBean {
/** id */
private String jobId;
/** 類名 */
private String jobClass;
/** 時間表達式 */
private String cronExpression;
/** 任務名稱 */
private String jobName;
public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobClass() {
return jobClass;
}
public void setJobClass(String jobClass) {
this.jobClass = jobClass;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public JobBean(String jobId, String jobClass, String cronExpression, String jobName) {
this.jobId = jobId;
this.jobClass = jobClass;
this.cronExpression = cronExpression;
this.jobName = jobName;
}
public JobBean() {
super();
}
}
新建Cron4jPlugin工具類
Cron4jPlugin:
package utils;
import it.sauronsoftware.cron4j.InvalidPatternException;
import it.sauronsoftware.cron4j.Scheduler;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import com.jfinal.plugin.IPlugin;
public class Cron4jPlugin implements IPlugin {
// 任務調度器
private static Scheduler scheduler = null;
// 任務
private static List<JobBean> jobs = new ArrayList<JobBean>();
// 任務配置文件
private String config = "job.properties";
private Properties properties;
public Cron4jPlugin(String config) {
this.config = config;
}
public Cron4jPlugin() {
}
/**
* 啟動任務調度器
*/
public boolean start() {
scheduler = new Scheduler();
// 加載配置文件
loadProperties();
Enumeration enums = properties.keys();
// 解析配置文件
while (enums.hasMoreElements()) {
String key = enums.nextElement() + "";
if (!key.endsWith("job")) {
continue;
}
String cronKey = key.substring(0, key.indexOf("job")) + "cron";
String enable = key.substring(0, key.indexOf("job")) + "enable";
String name = key.substring(0, key.indexOf("job")) + "name";
// 判斷是否自啟動
if (isDisableJob(enable)) {
continue;
}
String jobClassName = properties.get(key) + "";
String jobCronExp = properties.getProperty(cronKey) + "";
String jobName = properties.getProperty(name) + "";
Class clazz;
try {
clazz = Class.forName(jobClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
try {
// 添加一個調度任務;任務創建成功后會返回一個String類型的id,后續可以通過這個id操作這個任務
String jobId = scheduler.schedule(jobCronExp, (Runnable) clazz.newInstance());
jobs.add(createJob(jobId,jobClassName,jobCronExp,jobName));
} catch (InvalidPatternException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// 啟動調度器
scheduler.start();
return true;
}
private void loadProperties() {
properties = new Properties();
InputStream is = Cron4jPlugin.class.getClassLoader()
.getResourceAsStream(config);
try {
properties.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private boolean isDisableJob(String enable) {
return Boolean.valueOf(properties.get(enable) + "") == false;
}
/**
* 創建job
* @param id id
* @param className 類名
* @param cron 時間表達式
* @param name 任務
* @return
*/
private JobBean createJob(String id,String className,String cron,String name){
JobBean job = new JobBean();
job.setJobId(id);
job.setJobClass(className);
job.setCronExpression(cron);
job.setJobName(name);
return job;
}
/**
* 停止任務
* @param name 任務名
* @return
*/
public static boolean stopJob(String name) {
for (JobBean job : jobs) {
if(name.equals(job.getJobName())){
scheduler.deschedule(job.getJobId());
return true;
}
}
return false;
}
/**
* 停止任務調度器
*/
public boolean stop() {
scheduler.stop();
return true;
}
}
新建定時任務類
Testjob:
package utils;
import java.util.Date;
public class Testjob implements Runnable {
public void run() {
System.out.println("Current system time: " + new Date());
System.out.println("Another minute ticked away...");
}
}
properties配置文件
job.properties:
#job:任務類
#cron:執行的時間表達式
#enable:是否自啟動
#name:任務名
task1.job=utils.Testjob
task1.cron=*/1 * * * *
task1.enable=true
task1.name=task1
# 多個任務
#task2.job=utils.Testjob2
#task2.cron=*/2 * * * *
#task2.enable=true
#task2.name=task2
JFinal 核心類配置
public void configPlugin(Plugins me) {
me.add(new Cron4jPlugin());
}
停止任務
Cron4jPlugin.stopJob("task1");
調度模式(scheduling pattern)
scheduling pattern是一個 UNIX 的類定時任務模式,由一個以空格分隔為五個部分的字符串組成。從左到右依次為分、時、天、月、周。精確到秒則需要quartz。
字段 | 規則 |
---|---|
分 | 從 0 到 59 |
時 | 從 0 到 23 |
天 | 從 1 到 31,字母 L 可以表示月的最后一天 |
月 | 從 1 到 12,可以別名:jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov" and "dec" |
周 | 從 0 到 6,0 表示周日,6 表示周六,可以使用別名: "sun", "mon", "tue", "wed", "thu", "fri" and "sat" |
字符 | 用法 |
---|---|
n | 表示一個具體的時間點,例如 5 * * * * 表示 5 分這個時間點時執行 |
, | 表示指定多個數值,例如 3,5 * * * * 表示 3 和 5 分這兩個時間點執行 |
- | 表示范圍,例如 1-3 * * * * 表示 1 分、2 分再到 3 分這三個時間點執行 |
* | 表示每一個時間點,例如 * * * * * 表示每分鍾執行 |
/ | 表示指定一個值的增加幅度,例如 */5表示每隔5分鍾執行一次 |
常用的:
含義 | 價格 |
---|---|
每分鍾執行依次 | * * * * * |
每個小時執行一次 | 0 */1 * * * |
每天23:59執行一次 | 59 23 * * * |
每月最后一天的23:59執行一次 | 59 23 L * * |
每天9點到晚上9點,每個小時執行一次 | 0 9-21/1 * * * |
每天8點、10點、12點、14點、16點、18點各執行依次 | 0 8,10,12,14,16,18 * * * |
每個周六23:59執行一次 | 59 23 * * 6 59 23 * * sat |
一月份的每個周六23:59執行一次 | 59 23 * 1 6 59 23 * jan sat |