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

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

创建之后,表关系如图所示

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

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实现定时任务详解

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

来源:https://blog.csdn.net/Cavewang/article/details/126197742

标签:SpringBoot,Quartz,定时任务
0
投稿

猜你喜欢

  • Java数据结构之AC自动机算法的实现

    2023-08-31 07:23:57
  • MyBatis Generator 自定义生成注释的方法

    2023-02-24 12:37:23
  • java处理数据库不支持的emoji表情符问题解决

    2021-08-21 00:16:58
  • springsecurity 企业微信登入的实现示例

    2023-06-16 16:39:35
  • 深入剖析Android消息机制原理

    2023-09-30 01:57:11
  • 教你使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis)

    2021-09-23 12:37:42
  • Android 消息机制以及handler的内存泄露

    2023-08-01 07:59:44
  • JavaMap两种遍历方式keySet与entrySet详解

    2022-04-17 14:36:29
  • Java持久化XML文件配置解析

    2022-06-27 13:45:07
  • java模拟实现双向链表

    2022-06-05 09:16:16
  • java面向对象设计原则之合成复用原则示例详解

    2023-11-09 16:55:51
  • Java通过Scanner了解if...else if语句

    2023-11-29 04:28:44
  • 解析JavaSe的内部类

    2022-08-14 18:19:33
  • java写的伪微信红包功能示例代码

    2023-07-05 00:24:23
  • 老生常谈Java 网络编程 —— Socket 详解

    2023-07-12 16:32:54
  • 教你使用java实现去除各种空格

    2022-09-21 21:27:07
  • JAVA SPI特性及简单应用代码实例

    2021-11-11 14:54:54
  • java8到java15的新功能简介

    2023-07-28 02:18:18
  • Java中SimpleDateFormat日期格式转换详解及代码示例

    2023-09-04 22:13:43
  • 使用C++ Matlab中的lp2lp函数教程详解

    2023-07-13 17:13:12
  • asp之家 软件编程 m.aspxhome.com