SpringBoot整合Quartz实现定时任务详解

 更新时间:2022年08月08日 10:48:20   作者:Cavewang  
这篇文章主要介绍了Java 任务调度框架 Quartz,Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。,下面我们来学习一下关于 Quartz更多的详细内容,需要的朋友可以参考一下

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 = 5000

org.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();
        }
    }
}

运行结果

可以看到每隔十秒执行一次。

到此这篇关于SpringBoot整合Quartz实现定时任务详解的文章就介绍到这了,更多相关SpringBoot Quartz内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现简单的图书管理系统

    java实现简单的图书管理系统

    这篇文章主要为大家详细介绍了java实现简单的图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • mybatis 查询方式与效率高低对比

    mybatis 查询方式与效率高低对比

    这篇文章主要介绍了mybatis 查询方式与效率高低对比,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • SpringBoot 快速实现 api 加密的方法

    SpringBoot 快速实现 api 加密的方法

    在项目中,为了保证数据的安全,我们常常会对传递的数据进行加密,常用的加密算法包括对称加密(AES)和非对称加密(RSA),本文给大家介绍SpringBoot 快速实现 api 加密,感兴趣的朋友一起看看吧
    2023-10-10
  • Mybatis注解方式完成输入参数为list的SQL语句拼接方式

    Mybatis注解方式完成输入参数为list的SQL语句拼接方式

    这篇文章主要介绍了Mybatis注解方式完成输入参数为list的SQL语句拼接方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java内存模型中的虚拟机栈原理分析

    Java内存模型中的虚拟机栈原理分析

    这篇文章主要介绍了Java内存模型中的虚拟机栈原理分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java由浅入深带你精通继承super

    Java由浅入深带你精通继承super

    继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为
    2022-03-03
  • Java构建菜单树的实现示例

    Java构建菜单树的实现示例

    本文主要介绍了Java构建菜单树的实现示例,像一级菜单,二级菜单,三级菜单甚至更多层级的菜单,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • 最新IDEA 2022基于JVM极致优化 IDEA启动速度的方法

    最新IDEA 2022基于JVM极致优化 IDEA启动速度的方法

    这篇文章主要介绍了IDEA 2022最新版 基于 JVM极致优化 IDEA 启动速度,需要的朋友可以参考下
    2022-08-08
  • Java分布式学习之Kafka消息队列

    Java分布式学习之Kafka消息队列

    Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据
    2022-07-07
  • 教你怎么用Java数组和链表实现栈

    教你怎么用Java数组和链表实现栈

    本篇文章为大家详细介绍了怎么用Java数组和链表实现栈,文中有非常详细的代码示例及注释,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05

最新评论