Quartz+Spring Boot 注解实现CRUD定时任务

575 阅读1分钟

maven配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

yml配置

spring:
  application:
    name: quartz-auto
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
    username: root
    password: 123456

创建 QuartzConfig

@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
    SchedulerFactoryBean factory = new SchedulerFactoryBean();
    factory.setDataSource(dataSource);
    //quartz参数
    Properties prop = new Properties();
    prop.put("org.quartz.scheduler.instanceName", "safeScheduler");
    prop.put("org.quartz.scheduler.instanceId", "AUTO");
    //线程池配置
    prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
    prop.put("org.quartz.threadPool.threadCount", "20");
    prop.put("org.quartz.threadPool.threadPriority", "5");
    //JobStore配置
    prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
    //集群配置
    prop.put("org.quartz.jobStore.isClustered", "true");
    prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
    prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
    prop.put("org.quartz.jobStore.misfireThreshold", "2000");
    prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
    prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
    factory.setQuartzProperties(prop);

    return factory;
}

@Bean
public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) {
    Scheduler scheduler = schedulerFactoryBean.getScheduler();
    try {
        scheduler.start();
        log.info("schedule 已启动");
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
    return scheduler;
}

创建注解 QuartzJob

@Component
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface QuartzJob {
    String cron();
    String jobName();
    String jobGroupName();
    String triggerName();
    String triggerGroupName();
}

创建注解解析配置类,并在项目启动后加载,QuartzJobAutoRegisterConfig

@Resource
private ApplicationContext applicationContext;
@Resource
private Scheduler scheduler;

@Override
public void run(String... args) throws Exception {
    Map<String, Object> quartzJobMap = applicationContext.getBeansWithAnnotation(QuartzJob.class);
    if (quartzJobMap.isEmpty()) {
        return;
    }
    for (Map.Entry<String, Object> entry : quartzJobMap.entrySet()) {
        Object value = entry.getValue();
        Class<?> targetclass = AopUtils.getTargetClass(value);
        QuartzJob quartzJob = targetclass.getDeclaredAnnotation(QuartzJob.class);
        Quartzutil.addScheduleTask(quartzJob.jobName(), quartzJob.jobGroupName(),
                quartzJob.triggerName(), quartzJob.triggerGroupName(),
                quartzJob.cron(), Collections.emptyMap(),
                entry.getValue().getClass(), scheduler);
        log.info("success add job {}", entry.getValue().getClass());
    }
}

工具类 Quartzutil

public static void addScheduleTask(String jobName, String jobGroupName,
                                   String triggerName, String triggerGroupNameName,
                                   String cron, Map<String, Object> params, Class clazz, Scheduler scheduler) {
    try {
        //删除上个任务
        scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));//修改trigger
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(triggerName, triggerGroupNameName));
        if (Objects.isNull(trigger)) {
            trigger = buildTrigger(triggerName,
                    triggerGroupNameName, cron);
        } else {
            //设置新的调度
            trigger = trigger.getTriggerBuilder()
                    .withIdentity(TriggerKey.triggerKey(triggerName, triggerGroupNameName))
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron)
                            .withMisfireHandlingInstructionDoNothing())
                    .build();
        }
        //创建新的任务
        JobDetail jobDetail = buildJobDetail(jobName, jobGroupName, params, clazz);
        //加人quartz
        scheduler.scheduleJob(jobDetail, trigger);
    } catch (Exception e) {
        log.error("加入任务异常,", e);
    }
}


public static CronTrigger buildTrigger(String triggerName, String triggerGroupName, String cron) {
    return TriggerBuilder.newTrigger()
            .withIdentity(triggerName, triggerGroupName)
            .startNow()
            .withSchedule(CronScheduleBuilder.cronSchedule(cron)
                    //超时任务自动抛弃
                    .withMisfireHandlingInstructionDoNothing())
            .build();
}


public static JobDetail buildJobDetail(String jobName, String jobGroupName, Map<String, Object> params, Class clazz) {
    JobDataMap jobDataMap = new JobDataMap(params);
    return JobBuilder.newJob(clazz)
            .withIdentity(jobName, jobGroupName)
            .setJobData(jobDataMap)
            .build();
}

任务demo

@Slf4j
@QuartzJob(jobName = "auto-job",jobGroupName = "auto-job-g",triggerGroupName = "auto-job-t",triggerName ="auto-job-t-g",cron ="0/30 * * * * ?")
public class DemoJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("---------------大清亡了------------------");
    }
}

效果

image.png