jfinal扩展的定时任务插件。
maven依赖:
com.jfinal
jfinal
4.1
com.jfinal
jfinal-undertow
1.6
log4j
log4j
1.2.17
org.quartz-scheduler
quartz
2.2.1
com.google.guava
guava
18.0
日志配置: log4j.properties### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/debug.log
log4j.appender.R.DatePattern = '.'yyyy-MM-dd
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =logs/error.log
log4j.appender.E.DatePattern = '.'yyyy-MM-dd
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
QuartzPlugin源码:import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.IPlugin;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
import java.util.Map;
import java.util.Set;
public class QuartzPlugin implements IPlugin {
public static final String VERSION_1 = "1";
private static final String JOB = "job";
private final Log logger = Log.getLog(getClass());
private Map jobs = Maps.newLinkedHashMap();
private String version;
private SchedulerFactory sf;
private Scheduler scheduler;
private String jobConfig;
private String confConfig;
private Map jobProp;
public QuartzPlugin(String jobConfig, String confConfig) {
this.jobConfig = jobConfig;
this.confConfig = confConfig;
}
public QuartzPlugin(String jobConfig) {
this.jobConfig = jobConfig;
}
public QuartzPlugin() {
}
public QuartzPlugin add(String jobCronExp, Job job) {
jobs.put(job, jobCronExp);
return this;
}
@Override
public boolean start() {
loadJobsFromProperties();
startJobs();
return true;
}
private void startJobs() {
try {
if (StrKit.notBlank(confConfig)) {
sf = new StdSchedulerFactory(confConfig);
} else {
sf = new StdSchedulerFactory();
}
scheduler = sf.getScheduler();
} catch (SchedulerException e) {
Throwables.propagate(e);
}
Set> set = jobs.entrySet();
for (Map.Entry entry : set) {
Job job = entry.getKey();
String jobClassName = job.getClass().getName();
String jobCronExp = entry.getValue();
JobDetail jobDetail;
CronTrigger trigger;
//JobDetail and CornTrigger are classes in 1.x version,but are interfaces in 2.X version.
if (VERSION_1.equals(version)) {
jobDetail = Reflect.on("org.quartz.JobDetail").create(jobClassName, jobClassName, job.getClass()).get();
trigger = Reflect.on("org.quartz.CronTrigger").create(jobClassName, jobClassName, jobCronExp).get();
} else {
jobDetail = Reflect.on("org.quartz.JobBuilder").call("newJob", job.getClass()).call("withIdentity", jobClassName, jobClassName)
.call("build").get();
Object temp = Reflect.on("org.quartz.TriggerBuilder").call("newTrigger").get();
temp = Reflect.on(temp).call("withIdentity", jobClassName, jobClassName).get();
CronScheduleBuilder csb = Reflect.on("org.quartz.CronScheduleBuilder").call("cronSchedule", jobCronExp).get();
temp = Reflect.on(temp).call("withSchedule", csb).get();
trigger = Reflect.on(temp).call("build").get();
}
Date ft = Reflect.on(scheduler).call("scheduleJob", jobDetail, trigger).get();
logger.debug(Reflect.on(jobDetail).call("getKey") + " has been scheduled to run at: " + ft + " " +
"and repeat based on expression: " + Reflect.on(trigger).call("getCronExpression"));
}
try {
scheduler.start();
} catch (SchedulerException e) {
Throwables.propagate(e);
}
}
private void loadJobsFromProperties() {
if (StrKit.isBlank(jobConfig)) {
return;
}
jobProp = ResourceKit.readProperties(jobConfig);
Set> entries = jobProp.entrySet();
for (Map.Entry entry : entries) {
String key = entry.getKey();
if (!key.endsWith(JOB) || !isEnableJob(enable(key))) {
continue;
}
String jobClassName = jobProp.get(key) + "";
String jobCronExp = jobProp.get(cronKey(key)) + "";
Class job = Reflect.on(jobClassName).get();
try {
jobs.put(job.newInstance(), jobCronExp);
} catch (Exception e) {
Throwables.propagate(e);
}
}
}
private String enable(String key) {
return key.substring(0, key.lastIndexOf(JOB)) + "enable";
}
private String cronKey(String key) {
return key.substring(0, key.lastIndexOf(JOB)) + "cron";
}
public QuartzPlugin version(String version) {
this.version = version;
return this;
}
private boolean isEnableJob(String enableKey) {
Object enable = jobProp.get(enableKey);
if (enable != null && "false".equalsIgnoreCase((enable + "").trim())) {
return false;
}
return true;
}
@Override
public boolean stop() {
try {
scheduler.shutdown();
} catch (SchedulerException e) {
Throwables.propagate(e);
}
return true;
}
public QuartzPlugin confConfig(String confConfig) {
this.confConfig = confConfig;
return this;
}
public QuartzPlugin jobConfig(String jobConfig) {
this.jobConfig = jobConfig;
return this;
}
}