自己搭建spring boot 集成动态 quartz 任务

前几天公司里涉及到了一个定时任务的模块,不是很理解其原理,完全照着前人的路线重新敲了一遍,这两天空下来自己找了点资料来学习来,在自己的框架里搭建了quartz。
先建立一个实体类通过查询数据库里的数据来定下要执行的task

@Data
@Entity
@Table(name = "quartz_job")
public class QuartzJob implements Serializable {


    public static final String JOB_KEY = "JOB_KEY";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @NotNull(groups = {Update.class})
    private Long id;

    /**
     * 定时器名称
     */
    @Column(name = "job_name")
    private String jobName;

    /**
     * Bean名称
     */
    @Column(name = "bean_name")
    @NotBlank
    private String beanName;

    /**
     * 方法名称
     */
    @Column(name = "method_name")
    @NotBlank
    private String methodName;

    /**
     * 参数
     */
    @Column(name = "params")
    private String params;

    /**
     * cron表达式
     */
    @Column(name = "cron_expression")
    @NotBlank
    private String cronExpression;

    /**
     * 状态(0、启动;1、不启动)
     */
    @Column(name = "is_pause")
    private Boolean isPause = false;

    /**
     * 创建时间
     * */
    @UpdateTimestamp
    @Column(name = "create_date")
    private Date createDate;
    }

然后建立一个QuartzScheduler来启动注入任务

@Component
public class QuartzScheduler implements ApplicationRunner {

    @Autowired
    private QuartzDao quartzDao;

    @Autowired
    private QuartzJobManage quartzJobManage;

    @Override
    public void run(ApplicationArguments applicationArguments) {
        System.out.println("--------------------注入定时任务---------------------");
        List<QuartzJob> quartzJobList = quartzDao.getJob();
        quartzJobList.forEach(quartzJob -> {
            quartzJobManage.buildJob(quartzJob);
        });
        System.out.println("--------------------定时任务注入完成---------------------");
    }
}

QuartzJobManage:

@Slf4j
@Component
public class QuartzJobManage {

    private static final String JOB_NAME = "MYJOB_";

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

    public void buildJob(QuartzJob quartzJob){
        try {
            //创建一个jobDetail的实例,将该实例与HelloJob Class绑定
            JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class).withIdentity(JOB_NAME+quartzJob.getId()).build();
            //创建一个Trigger触发器的实例,定义该job立即执行
            Trigger trigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity(JOB_NAME+quartzJob.getId())
                    .startNow()
                    .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
                    .build();

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

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

            //执行定时任务
            scheduler.scheduleJob(jobDetail, trigger);
        }catch (Exception e){
            log.error("创建定时任务失败", e);
        }
    }


}

CronTrigger格式: [秒] [分] [小时] [日] [月] [周] [年]年可省略
通配符说明:
"表示所有值. 例如:在分的字段上设置 "”,表示每一分钟都会触发。
“?” 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10* ?
“-” 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。
“,” 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
“/“用于递增触发。如在秒上面设置"5/15” 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。
“L” 表示最后的意思。在日字段设置上,表示当月的最后一天
“W” 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W”,表示离每月15号最近的那个工作日触发。

ExecutionJob

@Async
public class ExecutionJob extends QuartzJobBean {

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

    private ExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    @Override
    public void executeInternal(JobExecutionContext context){

        QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);

        try {
            logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName());
            QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
                    quartzJob.getParams());
            Future<?> future = executorService.submit(task);
            future.get();
            logger.info("任务执行完毕");
        } catch (Exception e) {
            logger.error("任务执行失败,任务名称:{}" + quartzJob.getJobName(), e);
        }

    }

}

在QuartzRunnable里就是将beanname,methodName,param转成要的格式再implements Runnable 的方式跑动这个任务。
说起来quartz的理解和操作方式不难,只是需要将string格式的beanName找到相应的bean再放到JobDetail里,再通过设定CronTrigger再用scheduler来执行就好了,话说还有种SimpleTrigger,有兴趣的可以了解下,lz也只是刚学,写点理解,有不足希望指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值