1,spring整合quartz方式,這種網上資料太多,簡單引用一下就ok。
<bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/> <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="group" value="job_work"/> <property name="name" value="job_work_name"/> <!--false表示等上一個任務執行完后再開啟新的任務--> <property name="concurrent" value="false"/> <property name="targetObject"> <ref bean="taskJob"/> </property> <property name="targetMethod"> <value>run</value> </property> </bean> <!-- 調度觸發器 --> <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="name" value="work_default_name"/> <property name="group" value="work_default"/> <property name="jobDetail"> <ref bean="jobDetail" /> </property> <property name="cronExpression"> <value>0/5 * * * * ?</value> </property> </bean> <!-- 調度工廠 --> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="myTrigger"/> </list> </property> </bean>
2.spring task方式的定時任務(最為簡單,功能也簡單)
<!-- 定時器配置 開始--> <bean id="task1" class="com.XXX.Task1"></bean> <bean id="task2" class="com.XXX.Task2"></bean> <task:scheduled-tasks> <task:scheduled ref="task1" method="execute" cron="0 */1 * * * ?"/> <task:scheduled ref="task2" method="execute" cron="0 */1 * * * ?"/> </task:scheduled-tasks> <!-- 定時器配置 結束-->
使用的時候,直接寫一個類,一個方法就可以了,簡單快捷。task1類添加方法:
public void execute(){ // TODO: 你的業務邏輯 }
3.使用quartz方式,可以動態修改任務執行時間和參數的工具方法。
import java.util.List; import java.util.Set; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.JobBuilder; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.TriggerKey; import org.quartz.impl.DirectSchedulerFactory; import org.quartz.impl.matchers.GroupMatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 參考 * http://blog.csdn.net/xlxxcc/article/details/52115995 * @ClassName: QuartzManager * @author lishang * @Description quartz定時任務管理增刪改 * @date 2017年11月2日 下午1:27:47 * */ public class QuartzManager { protected static final Logger LOG = LoggerFactory.getLogger(QuartzManager.class); //private static SchedulerFactory schedulerFactory = new StdSchedulerFactory(); private static DirectSchedulerFactory schedulerFactory=DirectSchedulerFactory.getInstance(); static{ try { schedulerFactory.createVolatileScheduler(3); } catch (SchedulerException e) { LOG.info("創建DirectSchedulerFactory的Scheduler失敗!",e); } } /** * 判斷一個job是否存在 * @param jobName * @param jobGroupName * @param triggerName * @param triggerGroupName * @return */ public static boolean isExistJob(String jobName, String jobGroupName){ boolean exist=false; try { Scheduler sched = schedulerFactory.getScheduler(); JobKey jobKey = new JobKey(jobName, jobGroupName); exist = sched.checkExists(jobKey); } catch (SchedulerException e) { e.printStackTrace(); } return exist; } /** * @Description: 添加一個定時任務 * * @param jobName 任務名 * @param jobGroupName 任務組名 * @param triggerName 觸發器名 * @param triggerGroupName 觸發器組名 * @param jobClass 任務 * @param cron 時間設置,參考quartz說明文檔 */ @SuppressWarnings("unchecked") public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass,JobDataMap jMap, String cron) { try { Scheduler sched = schedulerFactory.getScheduler(); // 任務名,任務組,任務執行類 JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName) .usingJobData(jMap).build(); // 觸發器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 觸發器名,觸發器組 triggerBuilder.withIdentity(triggerName, triggerGroupName); triggerBuilder.startNow(); // 觸發器時間設定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 創建Trigger對象 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); // 調度容器設置JobDetail和Trigger sched.scheduleJob(jobDetail, trigger); Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey()); LOG.info("job的觸發器狀態:"+triggerState.name()); System.out.println("job的觸發器狀態:"+triggerState.name()); // 啟動 if (!sched.isShutdown()) { sched.start(); } //按新的trigger重新設置job執行 sched.rescheduleJob(trigger.getKey(), trigger); } catch (Exception e) { LOG.error("添加一個定時任務發生異常:",e); throw new RuntimeException(e); } } /** * @Description: 修改一個任務的觸發時間 * * @param jobName * @param jobGroupName * @param triggerName 觸發器名 * @param triggerGroupName 觸發器組名 * @param cron 時間設置,參考quartz說明文檔 */ public static void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName,@SuppressWarnings("rawtypes") Class jobClass,JobDataMap jMap,String cron) { /** 方式一 :調用 rescheduleJob 開始 */ // 觸發器 //TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 觸發器名,觸發器組 //triggerBuilder.withIdentity(triggerName, triggerGroupName); //triggerBuilder.startNow(); // 觸發器時間設定 //triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 創建Trigger對象 //trigger = (CronTrigger) triggerBuilder.build(); // 方式一 :修改一個任務的觸發時間 //sched.rescheduleJob(triggerKey, trigger); /** 方式一 :調用 rescheduleJob 結束 */ /** 方式二:先刪除,然后在創建一個新的Job */ removeJob(jobName, jobGroupName, triggerName, triggerGroupName); addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, jMap, cron); /** 方式二 :先刪除,然后在創建一個新的Job */ } /** * @Description: 移除一個任務 * * @param jobName * @param jobGroupName * @param triggerName * @param triggerGroupName */ public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { try { Scheduler sched = schedulerFactory.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); sched.pauseTrigger(triggerKey);// 停止觸發器 sched.unscheduleJob(triggerKey);// 移除觸發器 sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 刪除任務 List<String> jobGroupNames = sched.getJobGroupNames(); LOG.info("任務組開始-->groupsNames=["); for (String string : jobGroupNames) { GroupMatcher<JobKey> matcher=GroupMatcher.jobGroupEquals(string); Set<JobKey> jobKeys = sched.getJobKeys(matcher); LOG.info(string+"下的JOB為["); for (JobKey jobKey : jobKeys) { LOG.info(jobKey.getName()+","); } LOG.info("]"); } LOG.info("]任務組結束。"); } catch (Exception e) { LOG.error("移除job任務發生異常:",e); throw new RuntimeException(e); } } /** * @Description:啟動所有定時任務 */ public static void startJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); sched.start(); } catch (Exception e) { LOG.error("啟動所有定時任務發生異常:",e); throw new RuntimeException(e); } } /** * @Description:關閉所有定時任務 */ public static void shutdownJobs() { try { Scheduler sched = schedulerFactory.getScheduler(); if (!sched.isShutdown()) { sched.shutdown(); } } catch (Exception e) { LOG.error("關閉所有定時任務發生異常:",e); throw new RuntimeException(e); } } }
之前項目中使用的調度工廠類是:StdSchedulerFactory 然后定時任務動態修改的時候總是不穩定。后來改為上面的工廠類,問題得到了解決。
原因是其他地方有使用StdSchedulerFactory 的調度器,所有的調度任務都會在這個工廠中,不容易控制,而DirectSchedulerFactory這個工廠是每個new生成一個實例,更容易控制。
3.使用quartz方式,不整合spring