使用Spring + quartz实现定时任务调度

来源:互联网 发布:湖南软件外包公司 编辑:程序博客网 时间:2024/04/30 13:15

需求如下:用户可以设置定时发送短信.


一.环境准备

1.maven导入

    <dependency>        <groupId>org.quartz-scheduler</groupId>        <artifactId>quartz</artifactId>        <version>2.2.1</version>    </dependency>    <dependency>        <groupId>org.quartz-scheduler</groupId>        <artifactId>quartz-jobs</artifactId>        <version>2.2.1</version>    </dependency>

2.数据库建立quartz表

网上找.注意替换 ENGINE=InnoDB

3.classpath下创建配置文件:

quartz.properties

# Configure Main Scheduler Propertiesorg.quartz.scheduler.instanceName=MyTestQuartzorg.quartz.scheduler.instanceId=AUTOorg.quartz.scheduler.skipUpdateCheck=true# Configure ThreadPoolorg.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount=40org.quartz.threadPool.threadPriority=4 # Configure JobStore #org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore//保存在内存org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.dataSource=QRTZ_DS//默认前缀 可以按需修改org.quartz.jobStore.tablePrefix=QRTZ_ org.quartz.jobStore.isClustered=true#config datasourceorg.quartz.dataSource.QRTZ_DS.driver=com.mysql.jdbc.Driver org.quartz.dataSource.QRTZ_DS.URL=jdbc:mysql://10.1.1.1:3306/testdb?createDatabaseIfNotExist=true&autoReconnect=true&useUnicode=true&characterEncoding=utf8org.quartz.dataSource.QRTZ_DS.user=root org.quartz.dataSource.QRTZ_DS.password=rootorg.quartz.dataSource.QRTZ_DS.maxConnections=100# Configure Pluginsorg.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin 

二.Spring配置

applicationContext.quartz.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans            http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean name="schedulerFactoryBean" lazy-init="false"        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">        <property name="configLocation" value="classpath:quartz.properties" />    </bean>    <bean id="quartzService"        class="com.wlqq.mcs.admin.timer.quartz.service.impl.QuartzServiceImpl">        <property name="sched" ref="schedulerFactoryBean" />    </bean></beans>

三.代码清单

目录结构如下图所示
这里写图片描述

1.QuartzService.java

package xxx;import java.text.ParseException;import java.util.Date;import java.util.concurrent.TimeUnit;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.SchedulerException;public interface QuartzService {    /**     * 添加按间隔执行任务     * @param jobName 任务名称     * @param jobGroup 任务组名称     * @param triggerName 触发器名称     * @param triggerGroup 触发器组名称     * @param job 任务实例     * @param newJobDataMap 状态参数值     * @param interval 时间间隔     * @param timeUnit 时间单位     * @return     * @throws SchedulerException     * @throws ParseException     */    Date addIntervalJob(String jobName, String jobGroup, String triggerName,                        String triggerGroup, Job job, JobDataMap newJobDataMap,                        Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException;    /**     * 添加按间隔执行任务     * @param job 任务实例     * @param newJobDataMap 状态参数值     * @param interval 时间间隔     * @param timeUnit 时间单位     * @return     * @throws SchedulerException     * @throws ParseException     */    Date addIntervalJob(Job job, JobDataMap newJobDataMap,                        Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException;    /**     * 修改按间隔执行任务     * @param jobName 任务名称     * @param jobGroup 任务组名称     * @param triggerName 触发器名称     * @param triggerGroup 触发器组名称     * @param job 任务实例     * @param newJobDataMap 状态参数值     * @param interval 时间间隔     * @param timeUnit 时间单位     * @return     * @throws SchedulerException     * @throws ParseException     */    Date modifyIntervalJob(String jobName, String jobGroup, String triggerName,                           String triggerGroup, Job job, JobDataMap newJobDataMap,                           Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException;    /**     * 修改按间隔执行任务时间间隔     * @param triggerName 触发器名称     * @param triggerGroup 触发器组名称     * @param interval 时间间隔     * @param timeUnit 时间单位     * @return     * @throws SchedulerException     * @throws ParseException     */    Date modifyJobInterval(String triggerName, String triggerGroup,                           Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException;    /**     * 添加计划任务     * @param jobName 任务名称     * @param jobGroup 任务组名称     * @param triggerName 触发器名称     * @param triggerGroup 触发器组名称     * @param job 任务实例     * @param newJobDataMap 状态参数值     * @param cronExpression cron执行表达式     * @return     * @throws SchedulerException     * @throws ParseException     */    Date addCronJob(String jobName, String jobGroup, String triggerName,                    String triggerGroup, Job job, JobDataMap newJobDataMap, String cronExpression)            throws SchedulerException, ParseException;    /**     * 添加计划任务     * @param job 任务实例     * @param newJobDataMap 状态参数值     * @param cronExpression cron执行表达式     * @return     * @throws SchedulerException     * @throws ParseException     */    public Date addCronJob(Job job, JobDataMap newJobDataMap,String cronExpression)            throws SchedulerException, ParseException;    /**     * 修改计划任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroup     * @param job     * @param cronExpression     * @return     * @throws SchedulerException     * @throws ParseException     */    Date modifyCronJob(String jobName, String jobGroup, String triggerName,                       String triggerGroup, Job job, JobDataMap newJobDataMap, String cronExpression)            throws SchedulerException, ParseException;    /**     * 修改计划任务的触发时间     *      * @param triggerName     * @param triggerGroupName     * @param cronExpression     * @throws SchedulerException     * @throws ParseException     */    Date modifyCronJobTime(String triggerName, String triggerGroupName,                           String cronExpression) throws SchedulerException, ParseException;    /**     * 移除任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroupName     * @throws SchedulerException     */    boolean removeJob(String jobName, String jobGroup,                      String triggerName, String triggerGroupName)            throws SchedulerException;    /**     * 暂停任务     *      * @param jobName     * @param jobGroup     * @return     * @throws SchedulerException     */    void pauseJob(String jobName, String jobGroup,                  String triggerName, String triggerGroupName)            throws SchedulerException;    /**     * 恢复任务     *      * @param jobName     * @param jobGroup     * @return     * @throws SchedulerException     */    void resumeJob(String jobName, String jobGroup,                   String triggerName, String triggerGroupName)            throws SchedulerException;}

2.QuartzServiceImpl.java

package xxx;import static org.quartz.JobBuilder.newJob;import static org.quartz.TriggerBuilder.newTrigger;import java.text.ParseException;import java.util.Date;import java.util.UUID;import java.util.concurrent.TimeUnit;import org.quartz.CronScheduleBuilder;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.JobKey;import org.quartz.ScheduleBuilder;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SimpleScheduleBuilder;import org.quartz.Trigger;import org.quartz.TriggerKey;import xxx.QuartzService;public class QuartzServiceImpl implements QuartzService{    private Scheduler sched;    public void setSched(Scheduler sched) {        this.sched = sched;    }    private Date addJob(String jobName, String jobGroup, String triggerName,                        String triggerGroup, Job job, JobDataMap newJobDataMap,                        ScheduleBuilder scheduleBuilder) throws SchedulerException, ParseException  {        if (scheduleBuilder == null) {            return null;        }        JobBuilder builder = newJob(job.getClass());        builder.setJobData(newJobDataMap);        JobDetail jobDetail = builder.withIdentity(jobName, jobGroup).build();        // 触发器        Trigger trigger = newTrigger().withIdentity(triggerName, triggerGroup)                .withSchedule(scheduleBuilder)                .build();        Date date = sched.scheduleJob(jobDetail, trigger);        // 启动        if (!sched.isShutdown()) {            sched.start();        }        return date;    }    private Date modifyJobScheduler(String triggerName, String triggerGroupName,                                    ScheduleBuilder scheduleBuilder) throws SchedulerException, ParseException {        if (scheduleBuilder == null) {            return null;        }        TriggerKey key = new TriggerKey(triggerName, triggerGroupName);        Trigger trigger = sched.getTrigger(key);        if (trigger != null) {            trigger.getTriggerBuilder()                    .withSchedule(scheduleBuilder)                    .build();            return sched.rescheduleJob(key, trigger);        }        return null;    }    private SimpleScheduleBuilder intervalScheduleBuilder(Integer interval, TimeUnit timeUnit) {        SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().repeatForever();        switch (timeUnit) {            case MINUTES:                simpleScheduleBuilder.withIntervalInMinutes(interval);                break;            case HOURS:                simpleScheduleBuilder.withIntervalInHours(interval);                break;            case DAYS:                simpleScheduleBuilder.withIntervalInHours(interval * 24);                break;            default:                return null;        }        return simpleScheduleBuilder;    }    @Override    public Date addIntervalJob(String jobName, String jobGroup, String triggerName, String triggerGroup,                               Job job, JobDataMap newJobDataMap,                               Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException {        return addJob(jobName, jobGroup, triggerName, triggerGroup, job, newJobDataMap,                intervalScheduleBuilder(interval, timeUnit));    }    @Override    public Date addIntervalJob(Job job, JobDataMap newJobDataMap,                               Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException {        String id=UUID.randomUUID().toString().replaceAll("-", "");        return addIntervalJob(id, id, id, id, job, newJobDataMap, interval, timeUnit);    }    @Override    public Date modifyIntervalJob(String jobName, String jobGroup, String triggerName, String triggerGroup,                                  Job job, JobDataMap newJobDataMap,                                  Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException {        removeJob(jobName, jobGroup, triggerName, triggerGroup);        return addIntervalJob(jobName, jobGroup, triggerName, triggerGroup, job, newJobDataMap, interval, timeUnit);    }    @Override    public Date modifyJobInterval(String triggerName, String triggerGroup,                                  Integer interval, TimeUnit timeUnit) throws SchedulerException, ParseException {        return modifyJobScheduler(triggerName, triggerGroup, intervalScheduleBuilder(interval, timeUnit));    }    /**     * 添加任务     *      * @param jobName     *            任务名称     * @param jobGroup     *            任务组名称     * @param triggerName     *            触发器名称     * @param triggerGroup     *            触发器组名称     * @param job     *            任务实例     * @param cronExpression     *            cron表达式     * @throws SchedulerException     * @throws ParseException     */    public Date addCronJob(String jobName, String jobGroup, String triggerName,            String triggerGroup, Job job, JobDataMap newJobDataMap,            String cronExpression) throws SchedulerException, ParseException {        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);        return addJob(jobName, jobGroup, triggerName, triggerGroup, job, newJobDataMap, cronScheduleBuilder);    }    @Override    public Date addCronJob(Job job, JobDataMap newJobDataMap, String cronExpression)            throws SchedulerException, ParseException {        String id=UUID.randomUUID().toString().replaceAll("-", "");        return addCronJob(id, id, id, id, job, newJobDataMap, cronExpression);    }    /**     * 修改任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroup     * @param job     * @param cronExpression     * @return     * @throws SchedulerException     * @throws ParseException     */    public Date modifyCronJob(String jobName, String jobGroup, String triggerName,            String triggerGroup, Job job,JobDataMap newJobDataMap, String cronExpression)            throws SchedulerException, ParseException {        removeJob(jobName, jobGroup, triggerName, triggerGroup);        return addCronJob(jobName, jobGroup, triggerName, triggerGroup, job, newJobDataMap,                cronExpression);    }    /**     * 修改一个任务的触发时间     *      * @param triggerName     * @param triggerGroupName     * @param cronExpression     * @throws SchedulerException     * @throws ParseException     */    public Date modifyCronJobTime(String triggerName, String triggerGroupName,            String cronExpression) throws SchedulerException, ParseException {        return modifyJobScheduler(triggerName, triggerGroupName,                CronScheduleBuilder.cronSchedule(cronExpression));    }    /**     * 移除任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroupName     * @throws SchedulerException     */    public boolean removeJob(String jobName, String jobGroup,            String triggerName, String triggerGroupName)            throws SchedulerException {        TriggerKey key = new TriggerKey(triggerName, triggerGroupName);        sched.pauseTrigger(key);// 停止触发器        sched.unscheduleJob(key);// 移除触发器        JobKey jobKey = new JobKey(jobName, jobGroup);        return sched.deleteJob(jobKey);// 删除任务    }    /**     * 暂停任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroupName     * @throws SchedulerException     */    public void pauseJob(String jobName, String jobGroup, String triggerName,            String triggerGroupName) throws SchedulerException {        TriggerKey key = new TriggerKey(triggerName, triggerGroupName);        sched.pauseTrigger(key);// 停止触发器        JobKey jobKey = new JobKey(jobName, jobGroup);        sched.pauseJob(jobKey);// 停止任务    }    /**     * 恢复任务     *      * @param jobName     * @param jobGroup     * @param triggerName     * @param triggerGroupName     * @throws SchedulerException     */    public void resumeJob(String jobName, String jobGroup, String triggerName,            String triggerGroupName) throws SchedulerException {        TriggerKey key = new TriggerKey(triggerName, triggerGroupName);        sched.resumeTrigger(key);// 重启触发器        JobKey jobKey = new JobKey(jobName, jobGroup);        sched.resumeJob(jobKey);// 重启任务    }}

3.MassSmsJob.java (群发短信job)

package xxx.quartz.job;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;import xxx.commons.exceptions.BusinessException;import xxx.httpcommons.util.SpringContextUtil;import xxx.service.SmsMassService;/** * 群发短信job * @author Mingchenchen * */public class MassSmsJob implements Job{    public static final String SMS_MASS_JOB_GROUP = "smsMassJob"; // jobGroup    public static final String SMS_MASS_TRIGGER_GROUP = "smsMassTrigger"; // triggerGroup    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        JobDataMap datamap = context.getJobDetail().getJobDataMap();        String smsMassUuid = datamap.getString("uuid");        String title = datamap.getString("title");        String message = datamap.getString("message");        String phones = datamap.getString("phones");        try {            //此处就是定时任务实际执行的逻辑            SmsMassService smsMassService = SpringContextUtil.getBean(SmsMassService.class);            smsMassService.sendSms(smsMassUuid, title, message, phones);        } catch (BusinessException e) {            e.printStackTrace();        }    }}//业务逻辑 public void sendSms(String smsMassUuid, String title,        String message, String phones){    //调用sms群发短信    //TODO    //修改数据库标志位为已经发送    smsMassDao.setSended(smsMassUuid);}

4.CronExpressionUtils.java

package xxx.quartz.utils;import java.util.Calendar;import java.util.Date;public class CronExpressionUtils {    /**     * 根据一个时间解析成cron表达式     * @param date     * @return     */    public static String getCronExpressionByDate(Date date){        String cronExpression = "";        Calendar calendar = Calendar.getInstance();        calendar.setTime(date);        int year = calendar.get(Calendar.YEAR);        int month = calendar.get(Calendar.MONTH) + 1; //注意从0开始        int day = calendar.get(Calendar.DAY_OF_MONTH);        int hour = calendar.get(Calendar.HOUR_OF_DAY);        int minute = calendar.get(Calendar.MINUTE);        int second = calendar.get(Calendar.SECOND);        // "30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务,?是第几周 不指定        cronExpression = second + " " + minute + " " + hour + " "                + day + " " + month + " ? " + year;        return cronExpression;    }}

5.业务逻辑service调用 SmsMassServiceImpl.java

    @Value("${sms.mass.interval.minite:10}")    private int smsMassInterval; //群发短信的间隔,默认是10分钟    @Autowired    private SmsMassDao smsMassDao;    @Autowired    private QuartzService quartzService;    /**     * 创建定时任务     * @param uuid     * @param title     * @param message     * @param sendTime     * @param phones     * @throws BusinessException     */    private void createSmsMassCronJob(SmsMassRecord record) throws BusinessException{        MassSmsJob job = new MassSmsJob();        JobDataMap dataMap = new JobDataMap();        dataMap.put("uuid", record.getUuid());        dataMap.put("title", record.getTitle());        dataMap.put("message", record.getMessage());        dataMap.put("phones", record.getPhones());        String jobName = record.getUuid();        String jobGroup = MassSmsJob.SMS_MASS_JOB_GROUP;        String triggerName = record.getUuid();        String triggerGroup = MassSmsJob.SMS_MASS_TRIGGER_GROUP;        Date date = record.getSendTime();        String cronExpression = CronExpressionUtils.getCronExpressionByDate(date);        try {            quartzService.addCronJob(jobName, jobGroup, triggerName,                     triggerGroup, job, dataMap, cronExpression);        } catch (SchedulerException | ParseException e) {            e.printStackTrace();            throw new BusinessException(ResultCode.SYSTEM_EXCEPTION.code(), ResultCode.SYSTEM_EXCEPTION.message());        }    }

其他地方需要调用SpringContextUtil.getBean(QuartzService.class);即可

0 0