欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring boot 实现任务调度quartz

程序员文章站 2022-05-01 19:22:25
...

结合spring boot 实现quartz任务调度

  1. 首先在pom.xml中加入
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-quartz -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

  1. 实现Job接口
package com.cm.project.quartzs;

import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;


@Slf4j
@Component
public class ScheduleQuartzJob implements Job {

    @Autowired
    private TaskIntervalQuartz taskIntervalQuartz;

    private void before() {
        System.out.println("-----开始任务执行-----");
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        before();
        
        JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
        String jobName = jobKey.getName();
        // TODO 具体业务实现
        
        after();
    }

    private void after() {
        System.out.println("-----结束任务执行-----");
    }
}

  1. 具体实现调度方法
package com.cm.bmpbroadcast.quartzs;

import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TaskIntervalQuartz {

    private static String JOB_GROUP_NAME = "JOB_CLOUD_RADIOT";

    @Autowired
    private Scheduler scheduler;

    /**
     * 添加定时任务
     *
     * @param jobName 任务名称
     * @param time    时间
     * @throws Exception
     */
    public void addJob(Scheduler scheduler, String jobName, String time) throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(ScheduleQuartzJob.class).withIdentity(jobName, JOB_GROUP_NAME).build();
        // 基于表达式构建触发器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, JOB_GROUP_NAME)
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);

    }

    /**
     * 开启任务
     *
     * @param jobName 任务名称
     * @param time    时间
     */
    public void startJob(String jobName, String time) {
        try {
            addJob(scheduler, jobName, time);
            scheduler.start();
        } catch (SchedulerException e) {
            return;
        }
    }

    /**
     * 删除任务
     *
     * @param jobName 任务名称
     */
    public void deleteJob(String jobName) {
        try {
            JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
            scheduler.deleteJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 检测是否存在任务
     *
     * @param jobName
     * @return
     */
    public Boolean getJob(String jobName) {
        try {
            JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
            return scheduler.checkExists(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 恢复某个任务
     *
     * @param jobName 任务名称
     */
    public void resumeJob(String jobName) {
        try {
            JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail == null) {
                return;
            }
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.getUnderlyingException();
        }
    }
}

使用的是Cron表达式,所以, 需要拼接时间.
Cron表达式的规则:秒 分 时 日 月 周 年。除非有特定年,否则可以直接去掉。
Cron在线检查

在spring boot中可能会导致注入bean失败的情况,那么就需要手动注入

package com.cm.project.quartzs;

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfig {
    private JobFactory jobFactory;

    public QuartzConfig(JobFactory jobFactory){
        this.jobFactory = jobFactory;
    }

    /**
     * 配置SchedulerFactoryBean
     * 将一个方法产生为Bean并交给Spring容器管理
     * @return
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        // Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        // 设置自定义Job Factory,用于Spring管理Job bean
        factory.setJobFactory(jobFactory);
        return factory;
    }

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

package com.cm.project.quartzs;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

/**
 * 解决SpringBoot不能在Quartz中注入Bean的问题
 */
@Component
public class JobFactory extends AdaptableJobFactory {

    //将一个对象加入到SpringIOC容器中,并且完成对象注入
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    /**
     * 将实列化的任务对象手动加入到SpringIOC容器中,并且完成对象注入
     *
     * @param bundle
     * @return
     * @throws Exception
     */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object object = super.createJobInstance(bundle);
        //将object添加到SpringIOC容器中,并完成对象的注入
        this.autowireCapableBeanFactory.autowireBean(object);
        return object;
    }
}