<!--quartz相关依赖--><dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>${quartz.version}</version></dependency><dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>${quartz.version}</version></dependency>
@Configurationpublic class JobScheduleConfig { @Autowired private ApplicationContext applicationContext; @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setOverwriteExistingJobs(true); factory.setAutoStartup(true); //设置线程池 factory.setTaskExecutor(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2, new ThreadFactoryBuilder().setNameFormat("job-schedule-factory-thread-%d").build())); // factory.setQuartzProperties(quartzProperties()); AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); factory.setJobFactory(jobFactory); return factory; }
public final class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { beanFactory = applicationContext.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; }}
@Componentpublic class SchedulerJobFactory { public JobDetailFactoryBean job(Class<? extends QuartzJobBean> jobClass, JobDataMap jobMap, String jobName) { JobDetailFactoryBean jBean = createJobDetail(jobClass); jBean.setJobDataMap(jobMap); jBean.setBeanName(jobName); jBean.afterPropertiesSet(); return jBean; } private JobDetailFactoryBean createJobDetail(Class<? extends QuartzJobBean> jobClass) { JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); factoryBean.setJobClass(jobClass); factoryBean.setDurability(true); factoryBean.setRequestsRecovery(true); factoryBean.setBeanName(jobClass.getName()); return factoryBean; }}
@Componentpublic class SchedulerTriggerFactory { public CronTriggerFactoryBean jobTrigger(JobDetail jobDetail, String frequency, String triggerName) throws ParseException { CronTriggerFactoryBean tBean = createCronTrigger(jobDetail, frequency); tBean.setBeanName(triggerName); tBean.afterPropertiesSet(); return tBean; } private CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) { CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean(); factoryBean.setJobDetail(jobDetail); factoryBean.setCronExpression(cronExpression); factoryBean.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW); return factoryBean; }}
@Servicepublic class SchedulerJobService { private static final Logger LOGGER = LoggerFactory.getLogger(SchedulerJobService.class); @Autowired private SchedulerFactoryBean schedulerFactoryBean; @Autowired private SchedulerJobFactory schedulerJobFactory; @Autowired private SchedulerTriggerFactory schedulerTriggerFactory; @Resource private ApplicationContext applicationContext; @PostConstruct public void setupJobs() throws ParseException, SchedulerException { Map<String, AStandardBaseJob> beanMap = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, AStandardBaseJob.class); LOGGER.info("【task扫描注册已启动】-共找到task数为[{}]", beanMap != null ? beanMap.size() : 0); beanMap.keySet().forEach(key -> { AStandardBaseJob aStandardBaseJob = beanMap.get(key); String className = aStandardBaseJob.getClass().getName(); LOGGER.info("[------------扫描到的任务的名称为:" + className + "----------------------]"); }); if (beanMap != null && beanMap.size() > 0) { beanMap.forEach((key, value) -> { if (!this.baseCheck(value)) { return; } try { scheduleJob(value.getClass(), null, value.initCronValue(), StringBuilderHolder.getGlobal(). append(value.initAppId()).append("-").append(value.initCronKey()).toString(), value.initCronKey()); } catch (ParseException e) { e.printStackTrace(); } catch (SchedulerException e) { e.printStackTrace(); } }); } // scheduleJob(ContentStatisticsJob.class, null, "1/1 * * * * ?", // "exampleJob", "trigger1"); } public Date scheduleJob(Class<? extends QuartzJobBean> object, JobDataMap jMap, String frequency, String jobName, String triggerName) throws ParseException, SchedulerException { JobDetailFactoryBean jobDetailFactoryBean = schedulerJobFactory.job(object, jMap, jobName); CronTriggerFactoryBean cronTriggerFactoryBean = schedulerTriggerFactory .jobTrigger(jobDetailFactoryBean.getObject(), frequency, triggerName); return schedulerFactoryBean.getScheduler().scheduleJob(jobDetailFactoryBean.getObject(), cronTriggerFactoryBean.getObject()); } /** * 基本校验 * * @Description * @param aTaskStandardJob * @return */ public boolean baseCheck(AStandardBaseJob aTaskStandardJob) { if (StringUtils.isBlank(aTaskStandardJob.initAppId())) { LOGGER.error("【task扫描注册出现异常】-类[{}]-[appId]-不能为空", aTaskStandardJob.getClass()); return false; } if (StringUtils.isBlank(aTaskStandardJob.initCronKey())) { LOGGER.error("【task扫描注册出现异常】-类[{}]-[CronKey]-不能为空", aTaskStandardJob.getClass()); return false; } if (StringUtils.isBlank(aTaskStandardJob.initCronValue())) { LOGGER.error("【task扫描注册出现异常】-类[{}]-[CronValue]-不能为空", aTaskStandardJob.getClass()); return false; } if (aTaskStandardJob.initValidSign() == BaseGlobalConstants.VALID_SIGN_N) { LOGGER.info("【task扫描注册】-类[{}]-[valid_sign]-为无效", aTaskStandardJob.getClass()); return false; } return true; }}
public abstract class AStandardBaseJob extends QuartzJobBean{ /** * 初始化appid * * @Description * @return appId */ public abstract String initAppId(); /** * 初始化Cron表达式key * * @Description * @return cronKey */ public abstract String initCronKey(); /** * 初始化Cron表达式值 * * @Description * @return 表达式值 */ public abstract String initCronValue(); /** * 初始化有效标志 * * @Description * @return 表达式值 */ public abstract int initValidSign();}
<!--quartz依赖--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId></dependency>
在我们添加spring-boot-starter-quartz依赖后就不需要主动声明工厂类,因为spring-boot-starter-quartz已经为我们自动化配置好了。展开spring-boot-autoconfigure-2.0.0.RELEASE.jar,找到org.springframework.boot.autoconfigure.quartz,该目录就是SpringBoot为我们提供的Quartz自动化配置源码实现,在该目录下有如下所示几个类:
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;DROP TABLE IF EXISTS QRTZ_LOCKS;DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;DROP TABLE IF EXISTS QRTZ_TRIGGERS;DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS(SCHED_NAME VARCHAR(120) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,JOB_CLASS_NAME VARCHAR(250) NOT NULL,IS_DURABLE VARCHAR(1) NOT NULL,IS_NONCONCURRENT VARCHAR(1) NOT NULL,IS_UPDATE_DATA VARCHAR(1) NOT NULL,REQUESTS_RECOVERY VARCHAR(1) NOT NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,NEXT_FIRE_TIME BIGINT(13) NULL,PREV_FIRE_TIME BIGINT(13) NULL,PRIORITY INTEGER NULL,TRIGGER_STATE VARCHAR(16) NOT NULL,TRIGGER_TYPE VARCHAR(8) NOT NULL,START_TIME BIGINT(13) NOT NULL,END_TIME BIGINT(13) NULL,CALENDAR_NAME VARCHAR(200) NULL,MISFIRE_INSTR SMALLINT(2) NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_SIMPLE_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,REPEAT_COUNT BIGINT(7) NOT NULL,REPEAT_INTERVAL BIGINT(12) NOT NULL,TIMES_TRIGGERED BIGINT(10) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_CRON_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(120) NOT NULL,TIME_ZONE_ID VARCHAR(80),PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_SIMPROP_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(200) NOT NULL, TRIGGER_GROUP VARCHAR(200) NOT NULL, STR_PROP_1 VARCHAR(512) NULL, STR_PROP_2 VARCHAR(512) NULL, STR_PROP_3 VARCHAR(512) NULL, INT_PROP_1 INT NULL, INT_PROP_2 INT NULL, LONG_PROP_1 BIGINT NULL, LONG_PROP_2 BIGINT NULL, DEC_PROP_1 NUMERIC(13,4) NULL, DEC_PROP_2 NUMERIC(13,4) NULL, BOOL_PROP_1 VARCHAR(1) NULL, BOOL_PROP_2 VARCHAR(1) NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_BLOB_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_CALENDARS (SCHED_NAME VARCHAR(120) NOT NULL,CALENDAR_NAME VARCHAR(200) NOT NULL,CALENDAR BLOB NOT NULL,PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))ENGINE=InnoDB;CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))ENGINE=InnoDB;CREATE TABLE QRTZ_FIRED_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,ENTRY_ID VARCHAR(95) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,FIRED_TIME BIGINT(13) NOT NULL,SCHED_TIME BIGINT(13) NOT NULL,PRIORITY INTEGER NOT NULL,STATE VARCHAR(16) NOT NULL,JOB_NAME VARCHAR(200) NULL,JOB_GROUP VARCHAR(200) NULL,IS_NONCONCURRENT VARCHAR(1) NULL,REQUESTS_RECOVERY VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,ENTRY_ID))ENGINE=InnoDB;CREATE TABLE QRTZ_SCHEDULER_STATE (SCHED_NAME VARCHAR(120) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,LAST_CHECKIN_TIME BIGINT(13) NOT NULL,CHECKIN_INTERVAL BIGINT(13) NOT NULL,PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))ENGINE=InnoDB;CREATE TABLE QRTZ_LOCKS (SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME VARCHAR(40) NOT NULL,PRIMARY KEY (SCHED_NAME,LOCK_NAME))ENGINE=InnoDB;CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);commit;
*/
说明:
表字段说明:
表qrtz_job_details: 保存job详细信息,该表需要用户根据实际情况初始化job_name:集群中job的名字,该名字用户自己可以随意定制,无强行要求job_group:集群中job的所属组的名字,该名字用户自己随意定制,无强行要求job_class_name:集群中个note job实现类的完全包名,quartz就是根据这个路径到classpath找到该job类is_durable:是否持久化,把该属性设置为1,quartz会把job持久化到数据库中job_data:一个blob字段,存放持久化job对象表qrtz_triggers: 保存trigger信息trigger_name: trigger的名字,该名字用户自己可以随意定制,无强行要求trigger_group:trigger所属组的名字,该名字用户自己随意定制,无强行要求job_name: qrtz_job_details表job_name的外键job_group: qrtz_job_details表job_group的外键trigger_state:当前trigger状态,设置为ACQUIRED,如果设置为WAITING,则job不会触发;暂停任务时状态为PAUSEDtrigger_cron:触发器类型,使用cron表达式表qrtz_cron_triggers:存储cron表达式表trigger_name: qrtz_triggers表trigger_name的外键trigger_group: qrtz_triggers表trigger_group的外键cron_expression:cron表达式表qrtz_scheduler_state:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态instance_name:之前配置文件中org.quartz.scheduler.instanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字last_checkin_time:上次检查时间checkin_interval:检查间隔时间
spring.quartz.properties.org.quartz.scheduler.instanceName = clusteredSchedulerspring.quartz.properties.org.quartz.scheduler.instanceId = AUTOspring.quartz.properties.org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXspring.quartz.properties.org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegatespring.quartz.properties.org.quartz.jobStore.tablePrefix = qrtz_spring.quartz.properties.org.quartz.jobStore.isClustered = truespring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval = 10000spring.quartz.properties.org.quartz.jobStore.useProperties = falsespring.quartz.properties.org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolspring.quartz.properties.org.quartz.threadPool.threadCount = 2spring.quartz.properties.org.quartz.threadPool.threadPriority = 2spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = truespring.quartz.job-store-type = jdbcspring.quartz.startup-delay=5sspring.quartz.jdbc.initialize-schema=neverspring.quartz.overwrite-existing-jobs=false
@Componentpublic class TaskRunner implements ApplicationRunner { private final static Logger LOGGER = LoggerFactory.getLogger(TaskRunner.class); @Autowired private IQrtzJobDetailsService jobService; @Autowired private Scheduler scheduler; @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void run(ApplicationArguments var) throws Exception{ Long count = jobService.countQuartzEntity(); if(count==0){ LOGGER.info("初始化测试任务"); QuartzEntity quartz = new QuartzEntity(); quartz.setJobName("test01"); quartz.setJobGroup("test"); quartz.setDescription("测试任务"); quartz.setJobClassName("com.ambition.common.quartz.job.TestJob"); quartz.setCronExpression("0/20 * * * * ?"); Class cls = Class.forName(quartz.getJobClassName()) ; cls.newInstance(); //构建job信息 JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(), quartz.getJobGroup()) .withDescription(quartz.getDescription()).build(); // 触发时间点 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression()); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup()) .startNow().withSchedule(cronScheduleBuilder).build(); //交由Scheduler安排触发 scheduler.scheduleJob(job, trigger); } }}
任务类:
/** * 实现序列化接口、防止重启应用出现quartz Couldn't retrieve job because a required class was not found 的问题 * * Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。 * 其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。 * @DisallowConcurrentExecution 保证上一个任务执行完后,再去执行下一个任务,这里的任务是同一个任务 */@DisallowConcurrentExecutionpublic class TestJob implements Job,Serializable { private static final long serialVersionUID = 1L; @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("任务执行成功"); }}
controller类:
@Api(tags ="Quartz任务")@RestController@RequestMapping("/job")public class JobController { private final static Logger LOGGER = LoggerFactory.getLogger(JobController.class); @Autowired private Scheduler scheduler; @Autowired private IQrtzJobDetailsService jobService; @SuppressWarnings({ "unchecked", "rawtypes" }) @ApiOperation(value="新建任务") @PostMapping("/add") public R save(QuartzEntity quartz){ LOGGER.info("新增任务"); try { //获取Scheduler实例、废弃、使用自动注入的scheduler、否则spring的service将无法注入 //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //如果是修改 展示旧的 任务 if(quartz.getOldJobGroup()!=null){ JobKey key = new JobKey(quartz.getOldJobName(),quartz.getOldJobGroup()); scheduler.deleteJob(key); } Class cls = Class.forName(quartz.getJobClassName()) ; cls.newInstance(); //构建job信息 JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(), quartz.getJobGroup()) .withDescription(quartz.getDescription()).build(); // 触发时间点 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression()); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup()) .startNow().withSchedule(cronScheduleBuilder).build(); //交由Scheduler安排触发 scheduler.scheduleJob(job, trigger); } catch (Exception e) { LOGGER.error("",e); return R.error(); } return R.ok(); } @ApiOperation(value="任务列表") @PostMapping("/list") public R list(QuartzEntity quartz,Integer pageNo,Integer pageSize){ LOGGER.info("任务列表"); List<QuartzEntity> list = jobService.listQuartzEntity(); return R.ok(list); } @ApiOperation(value="触发任务") @PostMapping("/trigger") public R trigger(QuartzEntity quartz, HttpServletResponse response) { try { JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup()); scheduler.triggerJob(key); } catch (SchedulerException e) { e.printStackTrace(); return R.error(); } return R.ok(); } @PostMapping("/pause") public R pause(QuartzEntity quartz, HttpServletResponse response) { LOGGER.info("停止任务"); try { JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup()); scheduler.pauseJob(key); } catch (SchedulerException e) { e.printStackTrace(); return R.error(); } return R.ok(); } @PostMapping("/resume") public R resume(QuartzEntity quartz, HttpServletResponse response) { LOGGER.info("恢复任务"); try { JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup()); scheduler.resumeJob(key); } catch (SchedulerException e) { e.printStackTrace(); return R.error(); } return R.ok(); } @ApiOperation(value="移除任务") @PostMapping("/remove") public R remove(QuartzEntity quartz, HttpServletResponse response) { try { TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup()); // 停止触发器 scheduler.pauseTrigger(triggerKey); // 移除触发器 scheduler.unscheduleJob(triggerKey); // 删除任务 scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup())); System.out.println("removeJob:"+ JobKey.jobKey(quartz.getJobName())); } catch (Exception e) { e.printStackTrace(); return R.error(); } return R.ok(); }}
可以通过controller提供的接口进行任务的动态添加和删除,也可以和TaskRunner那样硬编码加载任务。