前言
个人地址:Quartz定时任务的基本搭建
Quartz是一个完全由Java编写的开源作业调度框架,为在java应用程序中进行作业调度提供了简单又强大的机制。
Quartz中分为几个核心概念:
- Job - 表示一个工作(任务),要执行的具体内容。
- JobDetail - 表示一个具体的可执行的调度程序,而Job就是这个可执行程序所要执行的内容,另外该调度程序还包含了任务的调度方案和策略。
- Trigger - 代表一个调度参数的配置(什么时候去调用)。
- Scheduler - 代表一个调度容器,一个调度容器可以注册多个“JobDetail”和"Trigger"。当“JobDetail”与“Trigger”组合在一起,就可以被“Scheduler”容器所调度了。
正式开始学习
正文即将开始兄弟别跑,跑了就不介绍小姐姐给你认识了。(/▽╲)
😌搭建项目环境
Tips: 看到这里,默认各位都是老司机了,项目创建就不占用朋友撩妹时间了。💯
转入正题 ===》 💞
既然要学习Quartz第一步肯定是引入相关的依赖包,需要的依赖我列在下面各位英雄自行摘取 ~~
<!-- 如果是springboot项目呢, 为了方便大家使用springboot已经进行了相关的整合, 仅引入以下starter的方式就完成了整合真的是居家旅行必备良药(ps.有没有跟小Y一起走错片场的呢)
-->
<!-- SpringBoot quartz依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency><!-- 其他(不引入上面starter的方式时引用) -->
<!-- Quartz核心依赖 -->
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version><scope>compile</scope>
</dependency>
🙂项目配置
接下来我们要做的就是在我们的项目中配置Quartz相关的配置类。
✔️ 首先:
我们知道quartz的几个核心概念中主要控制调度任务是由Scheduler调度器进行操作的,所以我们首先需要向Spring容器注入一个Scheduler调度器。
@Configuration
public class QuartzConfig {/*** 注册调度器创建工厂* @return 调度器工厂* @throws IOException ioe*/@Beanpublic SchedulerFactoryBean schedulerFactoryBean() throws IOException {PropertiesFactoryBean props = new PropertiesFactoryBean();props.setLocation(new ClassPathResource("/config/quartz.properties"));props.afterPropertiesSet();// 创建调度器工厂SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setQuartzProperties(Objects.requireNonNull(props.getObject()));return factory;}/*** 注册调度器* @return 调度器* @throws IOException ioe*/@Beanpublic Scheduler scheduler() throws IOException {return schedulerFactoryBean().getScheduler();}
}
以上配置仅为最简单的调度器注册方式,后续会根据相关api完善更多高级特性
✔️其次:
现在我们已经将Scheduler调度器注入到容器中,那我们现在需要做些什么?根据前言说到的“调度器”需要“JobDetail”和“Trigger”两样必须品才能开始进行任务调度。那么我们现在就需要将这两个必要参数交给Scheduler。
创建一个存放生成任务的实体
@Data
public class QuartzJob implements Serializable {private static final long serialVersionUID = 6481700930972512111L;/*** 任务名称*/private String jobName;/*** cron表达式*/private String cron;/*** bean全路径*/private String beanClass;/*** 任务分组*/private String jobGroup;/*** 执行参数*/private String jobData;
}
创建生成任务的工具类
@Component
public class QuartzJobUtil {@Resourceprivate Scheduler scheduler;/*** 添加任务* @param quartzJob job* @throws Exception e*/public void addJob(QuartzJob quartzJob) throws Exception {CronTrigger trigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(quartzJob.getJobName(), quartzJob.getJobGroup()));if (trigger != null) {return;}Class<?> clazz = Class.forName(quartzJob.getBeanClass());String quartzJobData = quartzJob.getJobData();Map dateMap = new HashMap<>();if (StrUtil.isNotBlank(quartzJobData)) {dateMap = (Map) JSON.parse(quartzJobData);}JobDataMap data = new JobDataMap(dateMap);JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) clazz).withIdentity(quartzJob.getJobName(), quartzJob.getJobGroup()).setJobData(data).build();// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCron());// 按新的表达式构建一个新的triggertrigger = TriggerBuilder.newTrigger().withIdentity(quartzJob.getJobName(), quartzJob.getJobGroup()).withSchedule(scheduleBuilder).build();scheduler.scheduleJob(jobDetail, trigger);}
}
✔️创建HelloWorld任务
正所谓一切皆从hello world开始,所以我们需要创建一个HelloWorldJob来完成测试功能。
@Slf4j
public class HelloWorldJob implements Job {private Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);private AtomicInteger counter = new AtomicInteger(0);@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {// 在这里我们简单的进行一下日志打印操作, 来证明任务被调度器调用logger.info("helloWorldJob执行第 {} - 次", counter.incrementAndGet());}
}
✔️将Job交给调度器
我们这里通过@PostConstruct注解在项目启动时,将HelloWorldJob交给调度器,让调度器进行管理并调用。
@PostConstruct
public void initializeJob() {// 启动时, 将job们加载至调度器中try {QuartzJob job = new QuartzJob();job.setJobName("helloWorldJob");job.setJobGroup("hello");job.setBeanClass(HelloWorldJob.class.getName());// 每分钟执行一次job.setCron("0 0/1 * * * ?");quartzJobUtil.addJob(job);} catch (Exception e) {log.error("定时任务加载失败....");e.printStackTrace();}
}
💯测试结果
我们Cron表达式设置的从0开始一分钟执行一次,所以当我们项目启动后,每到一分钟调度器就回执行一次我们的HelloWorld任务啦~😀
🔚End
本次学习结束~ 期待下一次学习分享~