简介
quartz,一个定时任务框架,比较简单。
快速开始
依赖关系
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <!--测试demo是idk8如果是更高版本则这里可以用新版本 --> <version>1.2.7</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency>
quartz.properties
# 实例名称 org.quartz.scheduler.instanceName=MyScheduler # 并发数 org.quartz.threadPool.threadCount=3 # 基于内存作为定时触发器 org.quartz.jobstore.class =org.quartz.simpl.RAMJobstore
logback.xml
<configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} - %magenta([%thread]) %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="CONSOLE" /> </root> </configuration>
QuartzTest
public class QuartzTest { @Test public void test01() throws SchedulerException { // 工厂模式获取定时器管理类,可以管理触发器 Triggers 和任务类 Job Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); scheduler.shutdown(); } }
执行打印日志,表示成功
自定义 Job 任务
自定义 Job,实现接口
org.quartz.Job
@Slf4j public class CustomJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info(String.format("任务执行…… %s", new Date())); } }
开启 job
@Test public void test01() throws SchedulerException, InterruptedException { // 工厂模式获取定时器管理类,可以管理触发器 Triggers 和任务类 Job Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 创建 Job 执行 JobDetail detail = JobBuilder.newJob(CustomJob.class).build(); // 创建一个 Trigger 触发器,立刻执行,设置其执行方式为每隔三秒执行一次,一直执行 SimpleTrigger trigger = TriggerBuilder .newTrigger() .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()) .build(); // 执行。开始定时器 scheduler.scheduleJob(detail, trigger); scheduler.start(); // 让主线程沉睡,同时观测定时器触发效果 TimeUnit.MINUTES.sleep(10000); scheduler.shutdown(); }
// 创建一个 Trigger 触发器 // 除了 startNow 之外,还可以指定开始和结束时间,还可以指定表达式 // 除了一直执行之外,还可以执行执行次数 withRepeatCount SimpleTrigger trigger = TriggerBuilder .newTrigger() .startAt(start_time) .endAt(end_time) .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).withRepeatCount(5)) .build();
任务数据存储
自定义 Job
@Slf4j // 可以在数据调度传递过程中修改数值 @PersistJobDataAfterExecution public class CustomJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); String username = jobDataMap.get("username").toString(); log.info(String.format("username -> %s", username)); Integer age = (Integer) jobDataMap.get("age"); log.info(String.format("age -> %s", age)); // 替换数据 jobDataMap.put("age", ++age); } }
定时器调度
@Test public void test02() throws SchedulerException, InterruptedException { // 工厂模式获取定时器管理类,可以管理触发器 Triggers 和任务类 Job Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("age", 10); // 创建 Job 执行 JobDetail detail = JobBuilder .newJob(CustomMapJob.class) // 在定时任务执行过程中传递数据 .usingJobData("username", "zhangsan") .usingJobData(jobDataMap) .build(); // 创建一个 Trigger 触发器,立刻执行,设置其执行方式为每隔三秒执行一次,一直执行 SimpleTrigger trigger = TriggerBuilder .newTrigger() .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()) .build(); // 执行。开始定时器 scheduler.scheduleJob(detail, trigger); scheduler.start(); // 让主线程沉睡,同时观测定时器触发效果 TimeUnit.MINUTES.sleep(10000); scheduler.shutdown(); }
cron 表达式
如果想要实现一些复杂操作,那么需要使用 cron 表达式
字段名 | 允许的值 | 允许的通配符 |
---|---|---|
秒 | 0 ~ 59 | , - * / |
分 | 0 ~ 59 | , - * / |
时 | 0 ~ 23 | , - * / |
日 | 1 ~ 31 | , - * ? / L W C |
月 | 1 ~ 12 or JAN ~ DEC | , - * / |
周几 | 1 ~ 7 or SUN ~ SAT | , - * ? / L C # |
年(可选字段) | empty | 1970 ~2099 , - * / |
cron 用于配置 cronTrigger 实例,可以直接到网络上查找一些在线表达式生成工具直接生成
@Test
public void test04() throws SchedulerException, InterruptedException {
// 工厂模式获取定时器管理类,可以管理触发器 Triggers 和任务类 Job
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 创建 Job 执行
JobDetail detail = JobBuilder.newJob(CustomJob.class).build();
Calendar calendar = Calendar.getInstance();
Date start_time = calendar.getTime();
calendar.add(Calendar.SECOND, 10);
Date end_time = calendar.getTime();
CronTrigger trigger = TriggerBuilder
.newTrigger()
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();
// 执行。开始定时器
scheduler.scheduleJob(detail, trigger);
scheduler.start();
// 让主线程沉睡,同时观测定时器触发效果
TimeUnit.MINUTES.sleep(10000);
scheduler.shutdown();
}
Trigger 传参
注意,trigger 虽然也可以进行传递参数,但是 trigger 中的数据不会发生变化,哪怕使用注解 @PersistJobDataAfterExecution
也一样
Job
@Slf4j // 可以在数据调度传递过程中修改数值 @PersistJobDataAfterExecution public class CustomTriggerMapJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobDataMap jobDataMap = jobExecutionContext.getTrigger().getJobDataMap(); String value = jobDataMap.get("trigger").toString(); log.info(String.format("trigger: %s", value)); } }
定时器调度
@Test public void test05() throws SchedulerException, InterruptedException { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail detail = JobBuilder.newJob(CustomTriggerMapJob.class).build(); CronTrigger trigger = TriggerBuilder .newTrigger() .startNow() .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) .build(); // 除了在 detail 中传递参数之外,还可以在 trigger 传递参数 trigger.getJobDataMap().put("trigger", "value"); scheduler.scheduleJob(detail, trigger); scheduler.start(); TimeUnit.MINUTES.sleep(10000); scheduler.shutdown(); }
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。