前言
个人地址: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
*/
@Bean
public 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
*/
@Bean
public 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 {
@Resource
private 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());
// 按新的表达式构建一个新的trigger
trigger = 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);
@Override
public 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
本次学习结束~ 期待下一次学习分享~