Jfinal实现定时任务调度

来源:互联网 发布:厦门软件学院 编辑:程序博客网 时间:2024/04/27 19:46

很多时候,我们会遇到让系统自动执行某段代码去执行业务相关逻辑。如生日短信通知,我们需要一个定时任务,获取到生日当天的所有用户,然后执行短信推送等业务逻辑,Jfinal是如何实现定时任务调度呢?

第一步:在Jfinal的过滤器中的configPlugin方法中加入自己实现的jfinal插件接口类配置。

@Overridepublic void configPlugin(Plugins me){QuartzPlugin plugin = new QuartzPlugin("job.properties");me.add(plugin);//...数据源等其他配置}

其中QuartzPlugin类的代码如下:
package com.wlkj.common.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import com.jfinal.plugin.IPlugin;

public class QuartzPlugin implements IPlugin {

private final Logger logger = Logger.getLogger(QuartzPlugin.class);private static final String JOB = "job";private String config = "job.properties";private Properties properties;public QuartzPlugin(String config) {    this.config = config;}public QuartzPlugin() {}private SchedulerFactory schedulerFactory;private Scheduler scheduler;@SuppressWarnings("unchecked")public boolean start() {    try {        loadProperties();    } catch (IOException e) {        logger.error(e.getMessage());        return false;    }    if (properties == null) {        return false;    }    schedulerFactory = new StdSchedulerFactory();    try {        scheduler = schedulerFactory.getScheduler();    } catch (SchedulerException e) {        logger.error(e.getMessage());        return false;    }    if (scheduler == null) {        logger.error("scheduler is null");        return false;    }    Enumeration<Object> enums = properties.keys();    while (enums.hasMoreElements()) {        String key = enums.nextElement() + "";        if (!key.endsWith(JOB) || !isTrue(getJobKey(key, "enable"))) {            continue;        }        String jobClassName = properties.get(key) + "";        String jobName = key.substring(0, key.lastIndexOf("."));        String jobCronExp = properties.getProperty(getJobKey(key, "cron")) + "";        String jobGroup = properties.getProperty(getJobKey(key, "group", "jobGroup1"));        Class<? extends Job> jobClass = null;        try {            jobClass = (Class<? extends Job>) Class.forName(jobClassName);        } catch (ClassNotFoundException e) {            logger.error(e.getMessage());            return false;        }        JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger", jobGroup)                .withSchedule(CronScheduleBuilder.cronSchedule(jobCronExp)).build();        try {            scheduler.scheduleJob(job, trigger);            scheduler.start();        } catch (SchedulerException e) {            logger.error(e.getMessage());            return false;        }    }    return true;}public boolean stop() {    try {        scheduler.shutdown();    } catch (SchedulerException e) {        logger.error(e.getMessage());        return false;    }    return true;}private void loadProperties() throws IOException {    properties = new Properties();    InputStream is = QuartzPlugin.class.getClassLoader().getResourceAsStream(config);    properties.load(is);}private String getJobKey(String str, String type, String defaultValue) {    String key = getJobKey(str, type);    if (key == null || "".equals(key.trim()))        return defaultValue;    return key;}private String getJobKey(String str, String type) {    return str.substring(0, str.lastIndexOf(JOB)) + type;}private boolean isTrue(String key) {    Object enable = properties.get(key);    if (enable != null && "false".equalsIgnoreCase((enable + "").trim())) {        return false;    }    return true;}

}
第二步:在classpath类路径下新建job.properties文件。
job.properties文件的内容如下:

birthday.job=com.wlkj.common.config.StatisticExecutorbirthday.cron=0 1 0 ? * *birthday.enable=truebirthday.group=1

注意:该文件的前缀必须相同,可随意取名,job的值com.wlkj.common.config.StatisticExecutor为执行任务调度的类
代码如下:

import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class StatisticExecutor implements Job{@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException{  //配置好后就会在规定的之间点执行这里的代码了,需要了解job.properties里birthday.cron表达式了  //# s m h d m w(?) y(?)   second minute hour date month week year }}

还得加入quartz的jar包,和slf4j-api和slf4j-log4j的jar

附:支持多任务调度

public boolean start() {        try {            loadProperties();        } catch (IOException e) {            logger.error(e.getMessage());            return false;        }        if (properties == null) {            return false;        }        Map<String, Object> jobMap = new HashMap<String, Object>();        Enumeration<Object> enums = properties.keys();        while (enums.hasMoreElements()) {            String key = enums.nextElement() + "";            if (!key.endsWith(JOB) || !isTrue(getJobKey(key, "enable"))) {                continue;            }            String jobName = key.substring(0, key.lastIndexOf("."));            if (!jobMap.containsKey(jobName)) {                Map<String, String> jobData = new HashMap<String, String>();                jobData.put("jobClassName", properties.getProperty(jobName + ".job") + "");                jobData.put("jobName", jobName);                jobData.put("jobCronExp", properties.getProperty(jobName + ".cron") + "");                jobData.put("jobGroup", properties.getProperty(jobName + ".group") + "");                jobMap.put(jobName, jobData);            }        }        for (String mapKey : jobMap.keySet()) {            Map<String, String> jobData = (Map<String, String>) jobMap.get(mapKey);            String jobClassName = jobData.get("jobClassName");            String jobName = jobData.get("jobName");            String jobCronExp = jobData.get("jobCronExp");            String jobGroup = jobData.get("jobGroup");            Class<? extends Job> jobClass = null;            try {                jobClass = (Class<? extends Job>) Class.forName(jobClassName);            } catch (ClassNotFoundException e) {                logger.error(e.getMessage());                return false;            }            JobDetail job = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger", jobGroup)                    .withSchedule(CronScheduleBuilder.cronSchedule(jobCronExp)).build();            try {                schedulerFactory = new StdSchedulerFactory();                try {                    scheduler = schedulerFactory.getScheduler();                } catch (SchedulerException e) {                    logger.error(e.getMessage());                    return false;                }                if (scheduler == null) {                    logger.error("scheduler is null");                    return false;                }                scheduler.scheduleJob(job, trigger);                scheduler.start();            } catch (SchedulerException e) {                logger.error(e.getMessage());                return false;            }        }        return true;    }

无非是获取到多个job名字用临时map进行存储,然后使用java反射机制遍历执行调度任务。