SpringBoot整合Quartz实现定时任务详解
作者:Cavewang 发布时间:2021-11-22 06:40:57
Quartz简介
Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB 作业预构建,JavaMail 及其它,支持 cron-like 表达式等等。
核心概念
主要有三个核心概念:调度器、任务和触发器。三者关系简单来说就是,调度器负责调度各个任务,到了某个时刻或者过了一定时间,触发器触动了,特定任务便启动执行。
Scheduler
Scheduler(调度器),基于trigger(触发器)的设定执行job(任务),代表一个Quartz的独立运行容器,Trigger和JobDetail要注册到Scheduler中才会生效,也就是让调度器知道有哪些触发器和任务,才能进行按规则进行调度任务。
JobDetail
Quartz 中需要执行的任务详情,包括了任务的唯一标识和具体要执行的任务,可以通过 JobDataMap 往任务中传递数据
Job
Job(任务),封装成JobDetail设置属性。
其中有两个重要注解
@DisallowConcurrentExecution :禁止并发的执行同一个job定义的多个实例
@PersistJobDataAfterExecution:持久化JobDetail中的JobDataMap(对trigger中的DataMap无效)
Trigger
Trigger(触发器),描述触发Job执行的时间触发规则。有SimpleTrigger和CronTrigger两个子类代表两种方式,一种是每隔多少分钟小时执行,则用SimpleTrigger;另一种是日历相关的重复时间间隔,如每天凌晨,每周星期一运行的话,通过Cron表达式便可定义出复杂的调度方案。
SpringBoot整合Quartz
准备数据库表
不同版本的quartz使用的数据库表不同,具体如下,选择对应版本即可
https://github.com/quartz-scheduler/quartz/tree/quartz-2.1.x
创建之后,表关系如图所示
Maven相关依赖
<!--spring连接驱动时,如com.mysql.cj.jdbc.Driver使用-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--quartz依赖-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
配置文件
application.yml
spring:
datasource:
username: xxx
password: xxxxxx
url: jdbc:mysql://localhost:3306/qrtz_db?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
spring-quartz.properties
#===================================================================
#配置JobStore
#===================================================================#JobDataMaps是否都为String类型,默认为false
org.quartz.jobStore.useProperties = false#表前缀
org.quartz.jobStore.tablePrefix = qrtz_#是否加入集群
org.quartz.jobStore.isClustered = true#调度实例失败的检查时间间隔 ms
org.quartz.jobStore.clusterCheckinInterval = 5000org.quartz.jobStore.txIsolationLevelReadCommitted = true
#数据保存方式为数据持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX#数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate#===================================================================
#配置Scheduler 调度器属性配置
#===================================================================#调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName = ClusterQuartz#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId = AUTO#===================================================================
#配置ThreadPool
#===================================================================#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有的用户)
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool#指定线程数,一般设定为1-100之间的整数,根据系统资源配置
org.quartz.threadPool.threadCount = 5#设置线程的优先级(可以是Thread.MIN_PRIORITY(即1)和Thread.MAX_PRIORITY(10)之间的任何int)
org.quartz.threadPool.threadPriority = 5
quartz配置类
@Configuration
public class SchedulerConfig {
@Autowired
private DataSource dataSource;
@Bean
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setSchedulerName("cluster_scheduler");
factory.setDataSource(dataSource);
factory.setApplicationContextSchedulerContextKey("application");
factory.setQuartzProperties(quartzProperties());
factory.setTaskExecutor(schedulerThreadPool());
factory.setStartupDelay(10);
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/spring-quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
@Bean
public Executor schedulerThreadPool(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(8);
return executor;
}
}
创建任务类
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class QuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Thread.sleep(2000);
System.out.println(context.getScheduler().getSchedulerInstanceId());
System.out.println("taskName="+context.getJobDetail().getKey().getName());
System.out.println("执行时间="+new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建监听类
@Component
public class StartApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private Scheduler scheduler;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
TriggerKey triggerKey = TriggerKey.triggerKey("trigger1","group1");
try {
Trigger trigger = scheduler.getTrigger(triggerKey);
if (trigger == null){
trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.startNow()
.build();
JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class)
.withIdentity("job1","group1")
.build();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
运行结果
可以看到每隔十秒执行一次。
来源:https://blog.csdn.net/Cavewang/article/details/126197742
猜你喜欢
- package airthmatic;public class demo10 { public static void main(
- intellij idea是一款非常优秀的软件开发工具,它拥有这强大的插件体系,可以帮助开发者完成很多重量级的功能。今天,我们来学习一下如何
- SqlMapConfig.xml的约束,也就是Mybatis主配置文件的约束<?xml version="1.0"
- 加载资源文件比较常用的有两种:一、用ClassLoader,说到这里就不得不提一下ClassLoader的分类,java内置的ClassLo
- 前言最近写一个东东,可能会考虑到字符串拼接,想了几种方法,但对性能未知,所以下面就来测试下面,话不多说了,来一起看看详细的介绍吧。示例代码p
- 程序如下:View Code /* * Hanoi塔游戏 问题描述: * 汉诺塔:汉诺塔(又称河内塔)问
- 分享一个在项目中用的到文件上传下载和对图片的压缩,直接从项目中扒出来的:)package com.eabax.plugin.yundada.
- 在新建Java项目时,run运行main方法时,报错 “java: 错误: 无效的源发行版:16”,
- SpringBoot访问html和js等静态资源配置把静态资源放到resources/static下,这是springboot静态资源默认访
- 常见Bean后处理器的作用:public static void main(String[] args) { &
- 本文实例讲述了java版微信公众平台消息接口应用方法。分享给大家供大家参考,具体如下:微信公众平台现在推出自动回复消息接口,但是由于是接口内
- 本文实例为大家分享了Java实现寻找迷宫出路的具体代码,供大家参考,具体内容如下项目名称寻找迷宫出路项目描述给定一个自定义迷宫,0表示能通过
- 本教程适合新手小白,Java7之前的版本是没有内置JavaFx的,Java7-10是内置JavaFx的,但是到了Java10以后的版本,Or
- 平时项目中只要涉及表,那么一定能接触到众多各式各样的ID编号,博主整理一些常用的ID格式,整合一个ID生成工具类,供大家参考,如果有什么不足
- 文件上传页面<%@ page language="java" contentType="text/htm
- 介绍了图的最小生成树的概念,然后介绍了求最小生成树的两种算法:Prim算法和Kruskal算法的原理,最后提供了基于邻接矩阵和邻接链表的图对
- 引言一个复杂的分布式系统,用户发起一个请求,这个请求可能调用几十到几百个服务,经过很多业务层,而每个业务又是多个机器集群,一个请求具体被随机
- Flyway是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。第一步:pom.xml添加maven依赖<!-- https
- Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 1.方法声明时使
- C#中Invoke的用法()invoke和begininvoke 区别一直对invoke和begininvoke的使用和概念比较混乱,这两天