JobStore是負責跟蹤調度器中全部的工做數據:做業任務、觸發器、日曆等。在配置文件(quartz.properties)中定義JobStore的形式,JobStore有兩種RAMJobStore和JDBCJobSTorejava
quartz.propertiesmysql
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
OK了,不須要別的配置,直接啓動正常運行就好。git
下載地址:點擊下方的Download now github
quartz.properties(這裏只給出主要配置,所有配置:參見github源碼)spring
# 持久化配置(存儲方式使用JobStoreTX,也就是數據庫) org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX #數據庫中quartz表的表名前綴 org.quartz.jobStore.tablePrefix:qrtz_ org.quartz.jobStore.dataSource:myQuartzDB #是否使用集羣(若是項目只部署到 一臺服務器,就不用了) org.quartz.jobStore.isClustered = true #============================================================================ # Configure Datasources配置數據源(可被覆蓋,若是在schedulerFactoryBean指定數據源) #============================================================================ org.quartz.dataSource.myQuartzDB.driver:com.mysql.jdbc.Driver org.quartz.dataSource.myQuartzDB.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 org.quartz.dataSource.myQuartzDB.user:root org.quartz.dataSource.myQuartzDB.password:root123 org.quartz.dataSource.myQuartzDB.maxConnections:10
OK了,正常啓動運行。sql
cronTrigger運行的話,數據保存部分表如
下:數據庫
QRTZ_CRON_TRIGGERS: TRIGGER_NAME、 TRIGGER_GROUP、 TRIGGER_EXPRESSION QRTZ_JOB_DETAIL: JOB_NAME、 JOB_GROUP、 JOB_CLASS_NAME QRTZ_TRIGGERS: TRIGGER_NAME、 TRIGGER_GROUP、 JOB_NAME、 JOB_GROUP、 JOB_CLASS_NAME、 START_TIME、 NEXT_FIRE_TIME、 PREV_FIRE_TIM、 MISFIRE_INSTR
注:從字段能夠看出QRTZ_TRIGGERS是一個整合表tomcat
pom.xmlspringboot
<!-- quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.7.RELEASE</version> </dependency> <!-- MySQL驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- druid數據源驅動 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
注:
spring-context-support
是spring爲了整合quartz及其餘框架的中間環境包
服務器
applicatin.yml
server: port: 8080 tomcat: uri-encoding: utf-8 spring: datasource: druid: # 數據庫訪問配置, 使用druid數據源 type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 username: root password: root123 name: anhusky
quartz.properties
#============================================================================ #基礎配置 #============================================================================ # 設置調度器的實例名(instanceName) 和實例ID (instanceId) org.quartz.scheduler.instanceName: MyScheduler #若是使用集羣,instanceId必須惟一,設置成AUTO org.quartz.scheduler.instanceId = AUTO #============================================================================ #調度器線程池配置 #============================================================================ org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool # 指定多少個工做者線程被建立用來處理 Job org.quartz.threadPool.threadCount: 20 # 設置工做者線程的優先級(最大值10,最小值1,經常使用值5) org.quartz.threadPool.threadPriority: 5 #============================================================================ #Configure JobStore 做業存儲配置 #============================================================================ # 持久化配置(存儲方式使用JobStoreTX,也就是數據庫) org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX #數據庫中quartz表的表名前綴 org.quartz.jobStore.tablePrefix:qrtz_ org.quartz.jobStore.misfireThreshold: 5000 #是否使用集羣(若是項目只部署到 一臺服務器,就不用了) org.quartz.jobStore.isClustered = false
SchduleConfig:爲ScheduleFactoryBean配置mysql數據源
/** * 定時任務配置 * * @author Administrator */ @Configuration public class ScheduleConfig { @Bean public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); // quartz參數 factory.setQuartzProperties(quartzProperties()); factory.setSchedulerName("MyScheduler"); // 延時啓動 factory.setStartupDelay(1); factory.setApplicationContextSchedulerContextKey("applicationContextKey"); // 可選,QuartzScheduler // 啓動時更新己存在的Job,這樣就不用每次修改targetObject後刪除qrtz_job_details表對應記錄了 factory.setOverwriteExistingJobs(true); // 設置自動啓動,默認爲true factory.setAutoStartup(true); /* CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setJobDetail( JobBuilder.newJob(ScheduleJob.class).build()); cronTriggerFactoryBean.setStartDelay(3000); cronTriggerFactoryBean.setCronExpression("0/10 * * * * ?"); // 經過這個設置 在項目啓動時啓動 factory.setTriggers(cronTriggerFactoryBean.getObject()); */ return factory; } /** * 加載Quartz配置 * * @return * @throws IOException */ @Bean public Properties quartzProperties() throws IOException { //使用Spring的PropertiesFactoryBean對屬性配置文件進行管理 PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); //注意:quartz的配置文件從指定系統目錄中獲取,而不是從classpath中獲取 propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); //propertiesFactoryBean.setLocation(new FileSystemResource(propertiesPath)); //重要:保證其初始化 propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } }
JobController
@RequestMapping(value = "/job") @Controller public class JobController { @Autowired private Scheduler scheduler; ``/** * 添加定時任務 */ @PostMapping("/addJob") @ResponseBody public Map<String, String> addJob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName, @RequestParam(value = "cronExpression") String cronExpression) { Map<String, String> returnData = new HashMap<>(); try { JobDetail jobDetail = JobBuilder .newJob(getClass(jobClassName).getClass()) .withIdentity("測試-1-jojobdetailbdetail") .build(); //構建CronTrigger觸發器 CronTrigger cronTrigger = TriggerBuilder .newTrigger() .withSchedule(cronSchedule(cronExpression) .withMisfireHandlingInstructionDoNothing() ) .withIdentity("測試-1-cronTrigger") .build(); //註冊調度任務 scheduler.scheduleJob(jobDetail, cronTrigger); //啓動任務 scheduler.start(); returnData.put("msg", "添加調度任務成功"); } catch (Exception e) { returnData.put("msg", "添加調度任務異常:" + e.getMessage()); } return returnData; } /** * 暫停定時任務 * * @param jobClassName * @param jobGroupName * @return */ @PutMapping(value = "/pauseJob") @ResponseBody public Map<String, String> pauseJob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); try { //JobKey定義了job的名稱和組別 JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName); //暫停任務 scheduler.pauseJob(jobKey); returnData.put("msg", "暫停調度任務成功"); } catch (SchedulerException e) { returnData.put("msg", "暫停調度任務異常:" + e.getMessage()); } catch (Exception e) { returnData.put("msg", "暫停調度任務異常:" + e.getMessage()); } return returnData; } /** * 啓動已經暫停的任務 * * @param jobClassName * @param jobGroupName * @return */ @PutMapping(value = "/resumeJob") @ResponseBody public Map<String, String> resumeJob(String jobClassName, String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); try { //JobKey定義了job的名稱和組別 JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName); //繼續任務 scheduler.resumeJob(jobKey); returnData.put("msg", "繼續調度任務成功"); } catch (SchedulerException e) { returnData.put("msg", "繼續調度任務異常:" + e.getMessage()); } catch (Exception e) { returnData.put("msg", "繼續調度任務異常:" + e.getMessage()); } return returnData; } /** * 更新定時任務: * --傳入的triggerKey有與之匹配的 * --舊觸發器的觸發時間沒有完成 * * @param jobClassName * @param jobGroupName * @param cronExpression * @return */ @PutMapping(value = "/rescheduleJob") @ResponseBody public Map<String, String> rescheduleJob(String jobClassName, String jobGroupName, String cronExpression) { Map<String, String> returnData = new HashMap<String, String>(); try { //構建舊的TriggerKey TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName); //經過cron表達式構建CronScheduleBuilder CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); //從調度容器中獲取舊的CronTrigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //更新CronTrigger trigger = trigger.getTriggerBuilder() .withIdentity(triggerKey) //工做項1:job名以及所屬組 .withSchedule(scheduleBuilder) //工做項2:指定調度參數 .build();//構建 //更新調度任務 scheduler.rescheduleJob(triggerKey, trigger); returnData.put("msg", "更新調度任務成功"); } catch (Exception e) { returnData.put("msg", "更新調度任務異常:" + e.getMessage()); } return returnData; } /** * @param jobClassName * @param jobGroupName * @return */ @DeleteMapping(value = "/removeJob") @ResponseBody public Map<String, String> removeJob(String jobClassName, String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); try { //得到調度容器 //Scheduler scheduler = getCurrentScheduler(); //TriggerKey定義了trigger的名稱和組別 TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName); //暫停觸發器 scheduler.resumeTrigger(triggerKey); //暫停觸發器 scheduler.unscheduleJob(triggerKey); //移除任務 scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName)); returnData.put("msg", "刪除調度任務成功"); } catch (SchedulerException e) { returnData.put("msg", "刪除調度任務異常:" + e.getMessage()); } catch (Exception e) { returnData.put("msg", "刪除調度任務異常:" + e.getMessage()); } return returnData; } /** * 得到指定的類實例 * * @param classname * @return * @throws ServerException */ private Job getClass(String classname) throws ServerException { Job baseJob = null; try { //加載參數指定的類 Class<?> classTmp = Class.forName(classname); //實例化 baseJob = (Job) classTmp.newInstance(); } catch (Exception e) { System.out.println(classname + "......找不到相應的類"); } return baseJob; } }