springboot项目持久层数据解析成Quartz定时任务

springboot配置不赘述
首先是Quartz的配置

@Configuration
public class QuartzConfig {
	//定时任务调度工厂
    @Autowired
    private TaskSchedulerFactory myJobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean () {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean ();
        schedulerFactoryBean.setJobFactory (myJobFactory);
        return schedulerFactoryBean;
    }

    @Bean
    public Scheduler scheduler () {
        return schedulerFactoryBean ().getScheduler ();
    }
}

其次调度工厂TaskSchedulerFactory

/**
 * 定时任务调度工厂,实现spring自动注入
 */

@Component
public class TaskSchedulerFactory extends AdaptableJobFactory{
    @Autowired  
    private AutowireCapableBeanFactory capableBeanFactory;  
  
    @Override  
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
        // 调用父类的方法  
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入  
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;  
    }
}

TaskSchedulerFactory中AutowireCapableBeanFactory 的作用可以使创建的JobDetail执行类进行自动注入

包装Scheduler创建TaskCronJobService定时任务服务类

@Service
public class TaskCronJobService {
    @Autowired
    private TimedTaskService timedTaskService;
    @Autowired
    private Scheduler scheduler;

    /**
     * 执行定时任务
     */
    public int executeTask (TimedTask timedTask) {
        JobKey jobKey = new JobKey (timedTask.getTaskId ().toString ());
        TriggerKey triggerKey = new TriggerKey (timedTask.getTaskId ().toString ());
        int index = 0;
        try {
            //查询触发器
            Trigger trigger = scheduler.getTrigger(triggerKey);
            //触发器存在则删除任务,确保定时任务的数据一致性
            if(null != trigger){
                scheduler.deleteJob (jobKey);
            }            
            //创建新任务 如果定时任务是启用状态
            if("0".equals (timedTask.getIsEnable ())){
                Class < ? > jobClass = Class.forName (timedTask.getServiceUrl () + "." + timedTask.getServiceName ());
                JobDetail jobDetail = JobBuilder.newJob ((Class < ? extends Job>) jobClass).withIdentity (jobKey)
                                    .withDescription (timedTask.getTaskDesc ()).build ();
                Trigger createTrigger=null;
                //cron表达式执行的定时任务
                if("0".equals (timedTask.getCycleExecution ())){
                    createTrigger = TriggerBuilder.newTrigger ().withIdentity(triggerKey).forJob (jobKey)
                            .withSchedule (CronScheduleBuilder.cronSchedule (timedTask.getCron ())
                                                              .withMisfireHandlingInstructionDoNothing ())
                            .build ();
                }else{
                	//间隔时间执行的定时任务
                    int hour = (timedTask.getHour ()==null||timedTask.getHour ().isEmpty ())?0:Integer.parseInt (timedTask.getHour ());
                    int minute = (timedTask.getMinute ()==null||timedTask.getMinute ().isEmpty ())?0:Integer.parseInt (timedTask.getMinute ());
                    int second = (timedTask.getSecond ()==null||timedTask.getSecond ().isEmpty ())?0:Integer.parseInt (timedTask.getSecond ());
                    //计算时分秒之后得到的间隔秒数
                    int num = (hour*60*60)+(minute*60)+second;
                    createTrigger = TriggerBuilder.newTrigger ().withIdentity(triggerKey).forJob (jobKey)
                            .withSchedule (SimpleScheduleBuilder.repeatSecondlyForever(num)).build ();
                }
                jobDetail.getJobDataMap ().put ("taskId", timedTask.getTaskId ());
                scheduler.scheduleJob(jobDetail, createTrigger);
            }
            //更新持久层的定时任务状态
            timedTask.setStatus ("0");
            //启动调度器  有时候运行没有问题但是定时任务不启动可能就是没有启动调度器
            scheduler.start ();
        } catch (Exception e) {
            timedTask.setStatus ("2");
        } finally {
            index = updateTimedTask(timedTask);
        }
        //返回数据库受影响的行数
        return index;
    }
    
    /**
     * 暂停定时任务
     */
    public int pauseTimedTask(Long taskId){
        JobKey jobKey = new JobKey (taskId.toString ());
        TimedTask timedTask = new TimedTask ();
        timedTask.setTaskId (taskId);
        timedTask.setIsEnable ("1");
        timedTask.setStatus ("0");
        try {
            scheduler.pauseJob (jobKey);
        } catch (SchedulerException e) {
            timedTask.setStatus ("2");
        }
        //更新持久层的定时任务状态
        return updateTimedTask (timedTask);
    }
    
    /**
     * 删除定时任务
     */
    public int deleteTimedTask(Long taskId){
        JobKey jobKey = new JobKey (taskId.toString ());
        TimedTask timedTask = new TimedTask ();
        timedTask.setTaskId (taskId);
        timedTask.setStatus ("-1");
        try {
            scheduler.deleteJob (jobKey);
        } catch (SchedulerException e) {
        }
        //更新持久层的定时任务状态
        return updateTimedTask (timedTask);
    }
    
    /**
     * 重启定时任务
     * 前台页面修改定时任务应该先走executeTask ()方法确保调度器中的定时任务数据和修改				后的定时任务数据一致,该方法只用于重启定时任务
     */
    public int restartTimedTask(Long taskId){
        JobKey jobKey = new JobKey (taskId.toString ());
        TriggerKey triggerKey = new TriggerKey (taskId.toString ());
        TimedTask tmp = new TimedTask ();
        tmp.setTaskId (taskId);
        tmp.setIsEnable ("0");
        tmp.setStatus ("0");
        try {
            Trigger trigger = scheduler.getTrigger(triggerKey);
            //如果没有该定时任务则直接创建
            if(null == trigger){
                TimedTask timedTask = timedTaskService.getTimedTaskForTaskId (taskId);
                Class < ? > jobClass = Class.forName (timedTask.getServiceUrl () + "." + timedTask.getServiceName ());
                JobDetail jobDetail = JobBuilder.newJob ((Class < ? extends Job>) jobClass).withIdentity (jobKey)
                                    .withDescription (timedTask.getTaskDesc ()).build ();
                Trigger createTrigger=null;
                if("0".equals (timedTask.getCycleExecution ())){
                    createTrigger = TriggerBuilder.newTrigger ().withIdentity(triggerKey).forJob (jobKey)
                            .withSchedule (CronScheduleBuilder.cronSchedule (timedTask.getCron ())
                                                              .withMisfireHandlingInstructionDoNothing ())
                            .build ();
                }else{
                    int hour = (timedTask.getHour ()==null||timedTask.getHour ().isEmpty ())?0:Integer.parseInt (timedTask.getHour ());
                    int minute = (timedTask.getMinute ()==null||timedTask.getMinute ().isEmpty ())?0:Integer.parseInt (timedTask.getMinute ());
                    int second = (timedTask.getSecond ()==null||timedTask.getSecond ().isEmpty ())?0:Integer.parseInt (timedTask.getSecond ());
                    int num = (hour*60*60)+(minute*60)+second;
                    createTrigger = TriggerBuilder.newTrigger ().withIdentity(triggerKey).forJob (jobKey)
                            .withSchedule (SimpleScheduleBuilder.repeatSecondlyForever(num)).build ();
                }
                jobDetail.getJobDataMap ().put ("taskId", timedTask.getTaskId ());
                scheduler.scheduleJob(jobDetail, createTrigger);
            }else{
            	//如果有该定时任务则直接重启
                scheduler.resumeJob (jobKey);
            }
        } catch (Exception e) {
            tmp.setStatus ("2");
        }
        return updateTimedTask (tmp);
    }
    
    /**
     * 更新定时任务到数据库
     * @param timedTask
     */
    @Transactional
    public int updateTimedTask(TimedTask timedTask){
        return timedTaskService.updateTimedTask (timedTask);
    }
}

最后是执行定时任务service

@Service
@DisallowConcurrentExecution//必须加该注解,否者会并发执行
public class TaskServiceImpl implements Job{
	//如果没有TaskSchedulerFactory的配置,则该属性无法自动注入@Autowired注解无效
    @Autowired
    private TimedTaskService service;
    
    @Override
    public void execute (JobExecutionContext context) throws JobExecutionException {
        //运行前更新状态为运行中
        Long taskId =  (Long) context.getJobDetail().getJobDataMap ().get ("taskId");
        TimedTask timedTask = new TimedTask ();
        timedTask.setStatus ("1");
        timedTask.setTaskId (taskId);
        service.updateTimedTask (timedTask);
        try{
            //业务代码
            ...
            
            //运行完毕更新状态为未运行
            timedTask.setStatus ("0");
        }catch (Exception e) {
          //运行出错更新状态为未运行
            timedTask.setStatus ("2");
        }finally {
            service.updateTimedTask (timedTask);
        }
        
    }
    
}

最后补充一个启动任务,启动项目后从数据库扫描符合条件的定时任务,然后加载

/**
 * 定时任务启动执行类,项目启动后扫描数据库加载定时任务
 */
@Component
@Order
public class TaskRunner implements ApplicationRunner{

    @Autowired
    private TimedTaskService timedTaskService;
    @Autowired
    private TaskCronJobService taskCronJobService;
    
    @Override
    public void run (ApplicationArguments args) throws Exception {
        Map<String, Object> params = new HashMap <String, Object> ();
        params.put ("isEnable", "0");
        List <TimedTask> list = timedTaskService.getTimedTaskList (params, 0, 999999);
        for (TimedTask timedTask : list) {
            taskCronJobService.executeTask (timedTask);
        }
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值