JFinal用cron4j执行定时任务
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 |