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,程序是否可以自动创建表)
分类:
Spring boot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-11-23 flume到hdfs和kafka
2021-11-23 flume sink到hdfs需要hadoop相关jar包,否则启动报错
2021-11-23 hadoop安装