自定义定时任务

本文展示了如何使用Quartz与SpringBoot集成来创建、更新、删除和执行动态定时任务。通过ThreadPoolExecutor实现线程池,确保异步处理任务,同时提供了暂停和恢复任务的功能。代码中还包括了实体类QuartzJob,用于存储任务信息,并在数据库中持久化。任务执行时,使用@Async注解实现异步方法,记录任务执行日志。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
    </dependency>

下面代码和实体类对象 制作定时任务配合线程池 异步处理

先配置线程池
task:
pool:
# 核心线程池大小
core-pool-size: 10
# 最大线程数
max-pool-size: 30
# 活跃时间
keep-alive-seconds: 60
# 队列容量
queue-capacity: 50

public class ThreadPoolExecutorUtil {

public static ThreadPoolExecutor getPoll(){
    AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class);
    return new ThreadPoolExecutor(
            properties.getCorePoolSize(),
            properties.getMaxPoolSize(),
            properties.getKeepAliveSeconds(),
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(properties.getQueueCapacity()),
            new TheadFactoryName()
    );
}

}

下面是创建 job

*/
@Slf4j
@Component
public class QuartzManage {

private static final String JOB_NAME = "TASK_";

@Resource(name = "scheduler")
private Scheduler scheduler;

public void addJob(QuartzJob quartzJob){
    try {
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class).
                withIdentity(JOB_NAME + quartzJob.getId()).build();

        //通过触发器名和cron 表达式创建 Trigger
        Trigger cronTrigger = newTrigger()
                .withIdentity(JOB_NAME + quartzJob.getId())
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
                .build();

        cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);

        //重置启动时间
        ((CronTriggerImpl)cronTrigger).setStartTime(new Date());

        //执行定时任务
        scheduler.scheduleJob(jobDetail,cronTrigger);

        // 暂停任务
        if (quartzJob.getIsPause()) {
            pauseJob(quartzJob);
        }
    } catch (Exception e){
        log.error("创建定时任务失败", e);
        throw new BadRequestException("创建定时任务失败");
    }
}

public void updateJobCron(QuartzJob quartzJob){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 如果不存在则创建一个定时任务
if(trigger == null){
addJob(quartzJob);
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
}
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//重置启动时间
((CronTriggerImpl)trigger).setStartTime(new Date());
trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob);

        scheduler.rescheduleJob(triggerKey, trigger);
        // 暂停任务
        if (quartzJob.getIsPause()) {
            pauseJob(quartzJob);
        }
    } catch (Exception e){
        log.error("更新定时任务失败", e);
        throw new BadRequestException("更新定时任务失败");
    }

}

/**
 * 删除一个job
 * @param quartzJob /
 */
public void deleteJob(QuartzJob quartzJob){
    try {
        JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
        scheduler.pauseJob(jobKey);
        scheduler.deleteJob(jobKey);
    } catch (Exception e){
        log.error("删除定时任务失败", e);
        throw new BadRequestException("删除定时任务失败");
    }
}

/**
 * 恢复一个job
 * @param quartzJob /
 */
public void resumeJob(QuartzJob quartzJob){
    try {
        TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 如果不存在则创建一个定时任务
        if(trigger == null) {
            addJob(quartzJob);
        }
        JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
        scheduler.resumeJob(jobKey);
    } catch (Exception e){
        log.error("恢复定时任务失败", e);
        throw new BadRequestException("恢复定时任务失败");
    }
}

/**
 * 立即执行job
 * @param quartzJob /
 */
public void runJobNow(QuartzJob quartzJob){
    try {
        TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 如果不存在则创建一个定时任务
        if(trigger == null) {
            addJob(quartzJob);
        }
        JobDataMap dataMap = new JobDataMap();
        dataMap.put(QuartzJob.JOB_KEY, quartzJob);
        JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
        scheduler.triggerJob(jobKey,dataMap);
    } catch (Exception e){
        log.error("定时任务执行失败", e);
        throw new BadRequestException("定时任务执行失败");
    }
}

/**
 * 暂停一个job
 * @param quartzJob /
 */
public void pauseJob(QuartzJob quartzJob){
    try {
        JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
        scheduler.pauseJob(jobKey);
    } catch (Exception e){
        log.error("定时任务暂停失败", e);
        throw new BadRequestException("定时任务暂停失败");
    }
}

}

public void updateIsPause(QuartzJob quartzJob) {
    if (quartzJob.getId().equals(1L)) {
        throw new BadRequestException("该任务不可操作");
    }
    if (quartzJob.getIsPause()) {
        quartzManage.resumeJob(quartzJob);
        quartzJob.setIsPause(false);
    } else {
        quartzManage.pauseJob(quartzJob);
        quartzJob.setIsPause(true);
    }
    this.saveOrUpdate(quartzJob);
}

@Override
public boolean save(QuartzJob quartzJob) {
    quartzManage.addJob(quartzJob);
    return retBool(baseMapper.insert(quartzJob));
}

@Override
public boolean updateById(QuartzJob quartzJob) {
    quartzManage.updateJobCron(quartzJob);
    return retBool(baseMapper.updateById(quartzJob));
}

/**
 * 立即执行定时任务
 *
 * @param quartzJob /
 */
@Override
public void execution(QuartzJob quartzJob) {
    if (quartzJob.getId().equals(1L)) {
        throw new BadRequestException("该任务不可操作");
    }
    quartzManage.runJobNow(quartzJob);
}

/**
 * 查询启用的任务
 *
 * @return List
 */
@Override
public List<QuartzJob> findByIsPauseIsFalse() {
    QuartzJobQueryCriteria criteria = new QuartzJobQueryCriteria();
    criteria.setIsPause(false);
    return baseMapper.selectList(QueryHelpPlus.getPredicate(QuartzJob.class, criteria));
}

@Override
public void removeByIds(List<Integer> idList) {
    idList.forEach(id -> {
        QuartzJob quartzJob = baseMapper.selectById(id);
        quartzManage.deleteJob(quartzJob);
    });
    baseMapper.deleteBatchIds(idList);
}

}

以及需要配置实体类 和数据库 进行保存 这样更灵活
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(“quartz_job”)
public class QuartzJob extends BaseDomain {

public static final String JOB_KEY = "JOB_KEY";

/** 定时任务ID */
@TableId
private Long id;


/** Spring Bean名称 */
private String beanName;


/** cron 表达式 */
private String cronExpression;


/** 状态:1暂停、0启用 */
private Boolean isPause;


/** 任务名称 */
private String jobName;


/** 方法名称 */
private String methodName;


/** 参数 */
private String params;


/** 备注 */
private String remark;



public void copy(QuartzJob source){
    BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}

}

以上代码就后才ok 实现 啦 现在 只需要 写一个方法

再放在实体类 对象
就可以玩了

@Async
public class ExecutionJob extends QuartzJobBean {

private Logger logger = LoggerFactory.getLogger(this.getClass());

/** 该处仅供参考 */
private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();

@Override
@SuppressWarnings("unchecked")
protected void executeInternal(JobExecutionContext context) {
    QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
    // 获取spring bean
    QuartzLogService quartzLogService = SpringContextHolder.getBean(QuartzLogService.class);
    QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);

    QuartzLog log = new QuartzLog();
    log.setJobName(quartzJob.getJobName());
    log.setBaenName(quartzJob.getBeanName());
    log.setMethodName(quartzJob.getMethodName());
    log.setParams(quartzJob.getParams());
    long startTime = System.currentTimeMillis();
    log.setCronExpression(quartzJob.getCronExpression());
    try {
        // 执行任务
        logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName());
        QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
                quartzJob.getParams());
        Future<?> future = EXECUTOR.submit(task);
        future.get();
        long times = System.currentTimeMillis() - startTime;
        log.setTime(times);
        // 任务状态
        log.setIsSuccess(true);
        logger.info("任务执行完毕,任务名称:{} 总共耗时:{} 毫秒", quartzJob.getJobName(), times);
    } catch (Exception e) {
        logger.error("任务执行失败,任务名称:{}" + quartzJob.getJobName(), e);
        long times = System.currentTimeMillis() - startTime;
        log.setTime(times);
        // 任务状态 0:成功 1:失败
        log.setIsSuccess(false);
        log.setExceptionDetail(ThrowableUtil.getStackTrace(e));
        quartzJob.setIsPause(false);
        //更新状态
        quartzJobService.updateIsPause(quartzJob);
    } finally {
        quartzLogService.save(log);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值