java若依框架定时任务

  • Post author:
  • Post category:java


定时任务工具类

package com.ruoyi.project.wxb.utils;

import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.exception.job.TaskException.Code;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.job.CronUtils;
import com.ruoyi.common.utils.job.QuartzDisallowConcurrentExecution;
import com.ruoyi.common.utils.job.QuartzJobExecution;
import com.ruoyi.project.monitor.domain.SysJob;
import org.quartz.*;

/**
 * 定时任务工具类
 *
 *
 */
public class ScheduleUtil
{
    /**
     * 得到quartz任务类
     *
     * @param sysJob 执行计划
     * @return 具体执行任务类
     */
    private static Class<? extends Job> getQuartzJobClass(SysJob sysJob)
    {
        boolean isConcurrent = "0".equals(sysJob.getConcurrent());
        return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
    }

    /**
     * 构建任务触发对象
     */
    public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
    {
        return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
    }

    /**
     * 构建任务键对象
     */
    public static JobKey getJobKey(Long jobId, String jobGroup)
    {
        return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
    }

    /**
     * 创建定时任务
     */
    public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
    {
        Class<? extends Job> jobClass = getQuartzJobClass(job);
        // 构建job信息
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();

        // 表达式调度构建器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
        cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);

        // 按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
                .withSchedule(cronScheduleBuilder).build();

        // 放入参数,运行时的方法可以获取
        jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);

        // 判断是否存在
        if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
        {
            // 防止创建时存在数据问题 先移除,然后在执行创建操作
            scheduler.deleteJob(getJobKey(jobId, jobGroup));
        }

        // 暂停任务
        if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
        {
            scheduler.pauseJob(ScheduleUtil.getJobKey(jobId, jobGroup));
        }

        // 判断任务是否过期
        if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression())))
        {
            // 执行调度任务
            scheduler.scheduleJob(jobDetail, trigger);
        }

    }

    /**
     * 设置定时任务策略
     */
    public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
            throws TaskException
    {
        switch (job.getMisfirePolicy())
        {
            case ScheduleConstants.MISFIRE_DEFAULT:
                return cb;
            case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
                return cb.withMisfireHandlingInstructionIgnoreMisfires();
            case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
                return cb.withMisfireHandlingInstructionFireAndProceed();
            case ScheduleConstants.MISFIRE_DO_NOTHING:
                return cb.withMisfireHandlingInstructionDoNothing();
            default:
                throw new TaskException("The task misfire policy '" + job.getMisfirePolicy()
                        + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
        }
    }

}

所需实体类

package com.ruoyi.project.monitor.domain;

import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.job.CronUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;

/**
 * 定时任务调度表 sys_job
 * 
 * @author ruoyi
 */
public class SysJob extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 任务ID */
    @Excel(name = "任务序号", cellType = ColumnType.NUMERIC)
    private Long jobId;

    /** 任务名称 */
    @Excel(name = "任务名称")
    private String jobName;

    /** 任务组名 */
    @Excel(name = "任务组名")
    private String jobGroup;

    /** 调用目标字符串 */
    @Excel(name = "调用目标字符串")
    private String invokeTarget;

    /** cron执行表达式 */
    @Excel(name = "执行表达式 ")
    private String cronExpression;

    /** cron计划策略 */
    @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行")
    private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;

    /** 是否并发执行(0允许 1禁止) */
    @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止")
    private String concurrent;

    /** 任务状态(0正常 1暂停) */
    @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
    private String status;

    public Long getJobId()
    {
        return jobId;
    }

    public void setJobId(Long jobId)
    {
        this.jobId = jobId;
    }

    @NotBlank(message = "任务名称不能为空")
    @Size(min = 0, max = 64, message = "任务名称不能超过64个字符")
    public String getJobName()
    {
        return jobName;
    }

    public void setJobName(String jobName)
    {
        this.jobName = jobName;
    }

    public String getJobGroup()
    {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup)
    {
        this.jobGroup = jobGroup;
    }

    @NotBlank(message = "调用目标字符串不能为空")
    @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符")
    public String getInvokeTarget()
    {
        return invokeTarget;
    }

    public void setInvokeTarget(String invokeTarget)
    {
        this.invokeTarget = invokeTarget;
    }

    @NotBlank(message = "Cron执行表达式不能为空")
    @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符")
    public String getCronExpression()
    {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression)
    {
        this.cronExpression = cronExpression;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date getNextValidTime()
    {
        if (StringUtils.isNotEmpty(cronExpression))
        {
            return CronUtils.getNextExecution(cronExpression);
        }
        return null;
    }

    public String getMisfirePolicy()
    {
        return misfirePolicy;
    }

    public void setMisfirePolicy(String misfirePolicy)
    {
        this.misfirePolicy = misfirePolicy;
    }

    public String getConcurrent()
    {
        return concurrent;
    }

    public void setConcurrent(String concurrent)
    {
        this.concurrent = concurrent;
    }

    public String getStatus()
    {
        return status;
    }

    public void setStatus(String status)
    {
        this.status = status;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("jobId", getJobId())
            .append("jobName", getJobName())
            .append("jobGroup", getJobGroup())
            .append("cronExpression", getCronExpression())
            .append("nextValidTime", getNextValidTime())
            .append("misfirePolicy", getMisfirePolicy())
            .append("concurrent", getConcurrent())
            .append("status", getStatus())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}
Scheduler是quartz包里面的,导入pom即可
	<!--引入quartz依赖-->
        <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>

数据库信息


多个参数逗号隔开

Cron表达式工具

@Component
public class CronUtil {

    // 每天执行
    private static final String DATE_FORMAT_EVERY_DAY = "ss mm HH * * ?";

    // 转换每天执行的cron表达式
    public static String getCronForEveryDay(String dateStr){
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_EVERY_DAY);
        SimpleDateFormat sdfInput = new SimpleDateFormat("HH:mm:ss");
        String cron = "error";
        try{
            Date date = sdfInput.parse(dateStr);
            cron = sdf.format(date);
        }catch (Exception e){
            e.printStackTrace();
        }
        return cron;
    }


}

service代码,mapper指向上文的数据库

package com.ruoyi.project.wxb.service.impl;

import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.utils.job.ScheduleUtils;
import com.ruoyi.project.monitor.domain.SysJob;
import com.ruoyi.project.wxb.entity.vo.R;
import com.ruoyi.project.wxb.mapper.QuartzMapper;
import com.ruoyi.project.wxb.service.QuartzService;
import com.ruoyi.project.wxb.utils.CronUtil;
import com.ruoyi.project.wxb.utils.ScheduleUtil;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;

@Service
public class QuartzServiceImpl implements QuartzService {
    @Autowired
    private QuartzMapper quartzMapper;
    @Autowired
    private Scheduler scheduler;


    public void init() throws SchedulerException, TaskException {
        scheduler.clear();
        List<SysJob> jobList = quartzMapper.getJobList();
        for (SysJob job : jobList) {
            ScheduleUtil.createScheduleJob(scheduler, job);
        }
    }

    @Override
    public R addJob(String jobId, String time, String invokeTarget, String name, String group) {
        try{
            SysJob sysJob = new SysJob();
            sysJob.setJobId(Long.valueOf(jobId));
            sysJob.setCronExpression(CronUtil.getCronForEveryDay(time));
            sysJob.setInvokeTarget(invokeTarget);
            sysJob.setJobName(name);
            sysJob.setJobGroup(group);
            quartzMapper.addJob(sysJob);
            return R.ok();
        }catch (Exception e){
            e.printStackTrace();
            return R.fail("插入Job失败!");
        }
    }

    @Override
    public void deleteJobs(List<Long> jobIdList) {
        quartzMapper.deleteJobs(jobIdList);
    }

    @Override
    public void updateJob(String startTime, String jobId) {
        String cron = CronUtil.getCronForEveryDay(startTime);
        quartzMapper.updateJob(cron,jobId);
    }

}

定时执行


@Configuration
@EnableScheduling
@Slf4j
public class JobSchedule {
    @Autowired
    private QuartzServiceImpl quartzService;

    //每天扫描一次
    @Scheduled(cron = "0 0 0 */1 * ?")
    private void carDefendTask() {
        log.info("JobSchedule start 启动 :" + System.currentTimeMillis());
        try {
            quartzService.init();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("JobSchedule error :" + System.currentTimeMillis()+"========="+e.getMessage());
        }
        log.info("JobSchedule end 结束 :" + System.currentTimeMillis());
    }
}

如果上述代码正确可以运行,这里的意思就是,定时执行ryTask里的ryNoParams方法,或执行ryParams方法,其参数为(‘ry’),可能需要在ryTask方法上添加@Service(”ryTask“)或者@Component(”ryTask“)

例如



版权声明:本文为weixin_59499726原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。