定时任务任务的三种方法
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
业务驱动技术,技术是手段,业务是目的。