springboot使用quartz

1.添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- jpa include HikariDataSource-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

2.添加配置,使用代码添加,不用quartz.propeites

import java.io.IOException;
import java.util.Properties;import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.SchedulerFactoryBean;



@Configuration
public class QuartzConfiguration {
    
    private Logger log = LoggerFactory.getLogger(QuartzConfiguration.class);

    @Autowired
    private JobFactory jobFactory;
    
    
    @Bean("schedulerFactory")
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "UranusQuartzScheduler");
        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");

        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        //prop.put("org.quartz.jobStore.dontSetAutoCommitFalse", "false");
        //prop.put("org.quartz.jobStore.isClustered", "true");
        //prop.put("org.quartz.jobStore.clusterCheckinInterval", "5000");
        //prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.dataSource", "uranusDB");
        prop.put("org.quartz.dataSource.uranusDB.provider", "hikaricp");
        prop.put("org.quartz.dataSource.uranusDB.driver", "com.mysql.cj.jdbc.Driver");
        prop.put("org.quartz.dataSource.uranusDB.URL", "jdbc:mysql://localhost:3306/uranus?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai");
        prop.put("org.quartz.dataSource.uranusDB.user", "root");
        prop.put("org.quartz.dataSource.uranusDB.password", "xxxxxxx");
        prop.put("org.quartz.dataSource.uranusDB.maxConnections", "10");
        
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        //prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");

        prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
        //config
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setQuartzProperties(prop);
        
        //
        factory.setSchedulerName("UranusQuartzScheduler");
        factory.setJobFactory(jobFactory);
        //factory.setStartupDelay(30);
        //factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        factory.setOverwriteExistingJobs(true);
        factory.setAutoStartup(true);

        return factory;
    }
    
   
 
    /**
     * 解析quartz.properties文件,填充属性
     * @return
     * @throws IOException
     */
    @Bean
    public Properties quartzProperties() throws IOException{
        
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();//propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        
        return propertiesFactoryBean.getObject();
    }
 
    /**
     * quartz初始化监听器
     * @return
     */
    @Bean
    public QuartzInitializerListener initializerListener(){
        
        //这个监听器可以监听到工程的启动,在工程停止再启动时可以让<已有的>定时任务继续进行
        //如果不开始监听,那么不会去读数据库,也就不会加载dataSource
        return new QuartzInitializerListener();
    }
 
    /**
     * 根据调度类工厂bean获取调度
     * @return
     * @throws IOException
     */
    @Bean("scheduler")
    public Scheduler scheduler() throws IOException{
        return schedulerFactoryBean().getScheduler();
    }
}

3.添加QuartzService

import com.alibaba.fastjson2.JSONObject;

public interface QuartzService {
    /**
     * 创建Job
     * @param job
     */
     Boolean addJob(JobEntity job);
 
    /**
     * 执行Job
     * @param job
     */
    Boolean runJob(JobEntity job);
 
    /**
     * 修改Job
     * @param job
     */
    Boolean updateJob(JobEntity job);
 
    /**
     * 暂定Job
     * @param job
     */
    Boolean pauseJob(JobEntity job);
 
    /**
     * 唤醒Job
     * @param job
     */
    Boolean resumeJob(JobEntity job);
 
    /**
     * 删除Job
     * @param job
     */
    Boolean deleteJob(JobEntity job);
 
    /**
     * 获取Job
     * @param job
     */
    JSONObject queryJob(JobEntity job);
}

 

4.实现QuartzServiceImpl

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONObject;
import com.nuctech.uranus.common.UranusConstant;
import com.nuctech.uranus.util.StringUtil;

@Service
public class QuartzServiceImpl implements QuartzService{
    
    private Logger log = LoggerFactory.getLogger(QuartzServiceImpl.class);
    
    @Autowired
    @Qualifier("scheduler")
    private Scheduler scheduler;
    

    /**
     * jobName -- task_code
     */
    @SuppressWarnings("unchecked")
    @Override
    public Boolean addJob(JobEntity job) {
        
        try {
             
            JSONObject data = job.getData();
            if(StringUtil.isNull(data)) {
                log.info("---addJob---data is null");
                return false;
            }
     
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.put(UranusConstant.QUARTZ_PATROL_DATA, data);//JobDetail.withIdentity对应数据库(JOB_NAME JOB_GROUP)
            //(JOB_NAME)似乎不支持中文
            JobDetail jobDetail = JobBuilder
                    .newJob((Class<? extends Job>) Class.forName(job.getClassName()))//指定执行类                    
                    .withIdentity(job.getJobName(), job.getJobGroup())// 指定name group                  
                    .requestRecovery().withDescription(job.getDescription())
                    .setJobData(jobDataMap)
                    .build();
            // 创建表达式调度构建器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder
                    .cronSchedule(job.getCronExpression());
            // 创建触发器
            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(job.getTriggerName(), job.getTriggerGroup())
                    .withDescription(job.getDescription())
                    .withSchedule(cronScheduleBuilder).build();//withPriority()
            //
            scheduler.scheduleJob(jobDetail, cronTrigger);
            scheduler.start();

            return true;
        } catch (Exception e) {
            
            log.info("---addJob---发生异常:");
            e.printStackTrace();
        }
        return false;
    }

    /**
     * JobName
     * JobGroup
     */
    @Override
    public Boolean runJob(JobEntity job) {
        
        try {
            scheduler.triggerJob(JobKey.jobKey(job.getJobName(),job.getJobGroup()));
            log.info("---runJob---定时任务[{}]执行成功", job.getJobName());
            
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public Boolean updateJob(JobEntity job) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean pauseJob(JobEntity job) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Boolean resumeJob(JobEntity job) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * JobName
     * JobGroup
     */
    @Override
    public Boolean deleteJob(JobEntity job) {
        
        try {
            scheduler.deleteJob(JobKey.jobKey(job.getJobName(), job.getJobGroup()));
            log.info("---deleteJob---定时任务[{}]删除成功", job.getJobName());
            
            return true;
        } catch (Exception e) {
            
            log.info("---deleteJob---异常-");
            e.printStackTrace();
        }
        return false;
    }

    /**
     * JobName
     * JobGroup
     */
    @SuppressWarnings({ "unchecked", "unused" })
    @Override
    public JSONObject queryJob(JobEntity job) {
        
        CronTrigger ct = null;
        try {
            
            List<CronTrigger> triggers = (List<CronTrigger>) scheduler.getTriggersOfJob(JobKey.jobKey(job.getJobName(), job.getJobGroup()));
            log.info("---queryJob---triggers size:"+triggers.size());
            ct = triggers.get(0);
            
        } catch (SchedulerException e1) {
            
            log.info("---queryJob---异常-");
            e1.printStackTrace();
            return null;
        }
        log.info("---queryJob---triggerkey:"+ct.getKey().getName()+"  triggerGroup:"+ct.getKey().getGroup());
        
        if(null == ct) {
            return null;
        }
        TriggerKey triggerKey = ct.getKey();
        try {//
            TriggerState ts = scheduler.getTriggerState(triggerKey);
        
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("triggerState", ts);
            return jsonObject;
        } catch (Exception e) {
            
            log.info("---queryJob---异常-");
            e.printStackTrace();
        }
        return null;
    }

}

5.实现JobEntity

import java.util.Date;

import com.alibaba.fastjson2.JSONObject;

public class JobEntity  {
    private String jobId; //唯一id
    private String className; //定时任务示例的 class路径
    private String cronExpression; //cron表达式
    private String jobName; //定时任务名称
    private String jobGroup; //所属组
    private String triggerName; //触发器名称
    private String triggerGroup; //触发器组
    private String description; //备注
    private JSONObject data; //携带参数
 
    /**
     * 预留的数据库字段 如果任务信息选择手动自己存入数据库的话,会使用到
     */
    private Boolean pauseStatus;  //是否暂停
    private Boolean deleteStatus; //是否有效
    private Date createTime; //创建时间
    private Date updateTime; //更新时间
 
 
    @Override
    public String toString() {
        return "JobEntity{" +
                "jobId='" + jobId + '\'' +
                ", className='" + className + '\'' +
                ", cronExpression='" + cronExpression + '\'' +
                ", jobName='" + jobName + '\'' +
                ", jobGroup='" + jobGroup + '\'' +
                ", triggerName='" + triggerName + '\'' +
                ", triggerGroup='" + triggerGroup + '\'' +
                ", description='" + description + '\'' +
                ", data=" + data +
                ", pauseStatus=" + pauseStatus +
                ", deleteStatus=" + deleteStatus +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                '}';
    }
 
    public String getJobId() {
        return jobId;
    }
 
    public void setJobId(String jobId) {
        this.jobId = jobId;
    }
 
    public String getClassName() {
        return className;
    }
 
    public void setClassName(String className) {
        this.className = className;
    }
 
    public String getCronExpression() {
        return cronExpression;
    }
 
    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }
 
    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;
    }
 
    public String getTriggerName() {
        return triggerName;
    }
 
    public void setTriggerName(String triggerName) {
        this.triggerName = triggerName;
    }
 
    public String getTriggerGroup() {
        return triggerGroup;
    }
 
    public void setTriggerGroup(String triggerGroup) {
        this.triggerGroup = triggerGroup;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public JSONObject getData() {
        return data;
    }
 
    public void setData(JSONObject data) {
        this.data = data;
    }
 
    public Boolean getPauseStatus() {
        return pauseStatus;
    }
 
    public void setPauseStatus(Boolean pauseStatus) {
        this.pauseStatus = pauseStatus;
    }
 
    public Boolean getDeleteStatus() {
        return deleteStatus;
    }
 
    public void setDeleteStatus(Boolean deleteStatus) {
        this.deleteStatus = deleteStatus;
    }
 
    public Date getCreateTime() {
        return createTime;
    }
 
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
 
    public Date getUpdateTime() {
        return updateTime;
    }
 
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}

6.创建JobFactory

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;

@Component
public class JobFactory extends AdaptableJobFactory{

    
    @Autowired
    private AutowireCapableBeanFactory beanFactory;
 
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle)
            throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        //Job实例注入到Job工厂
        beanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

 

7.创建Job,即触发时响应的执行方法

import java.util.List;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson2.JSONObject;
import com.nuctech.uranus.common.UranusConstant;
import com.nuctech.uranus.domain.PatrolTaskExecuteDomain;
import com.nuctech.uranus.model.RobotModel;
import com.nuctech.uranus.mongo.PatrolTaskExecuteMongo;
import com.nuctech.uranus.mongo.RobotModelMongo;
import com.nuctech.uranus.util.TimeUtil;

public class PatrolExecuteJob implements Job{
    
    private Logger log = LoggerFactory.getLogger(PatrolExecuteJob.class);
    
    @Autowired
    private RobotModelMongo robotModelMongo;
    
    @Autowired
    private PatrolTaskExecuteMongo patrolTaskExecuteMongo; 
    
    
    
    /**
     * 一个robot_code会带有多个task_code
     * 一个task_code每执行一次就有一个exec_code
     * 
     * robot_code
     * task_code
     * exec_code
     */
    @SuppressWarnings("unchecked")
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        
        log.info("---execute---");
        
        String taskCode = context.getJobDetail().getKey().getName();//task_code
        log.info("---execute---jobName:"+taskCode);
        
        log.info("---execute---当前线程名[{}]",Thread.currentThread().getName());
    }

}

 

8.创建数据库并写入表(tables_mysql.sql, 在下载的quartz-2.3.2包里有,可以试一下不执行sql,程序是否可以自动创建表)

posted @ 2022-11-23 16:04  jason47  阅读(262)  评论(0编辑  收藏  举报