• Java-Quartz实现定时任务(SpringBoot整合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相关依赖

            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <scope>runtimescope>
            dependency>
            
            <dependency>
                <groupId>org.quartz-schedulergroupId>
                <artifactId>quartz-jobsartifactId>
                <version>2.2.2version>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-quartzartifactId>
            dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    配置文件

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    创建任务类

    @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();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    创建监听类

    @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();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    运行结果

    在这里插入图片描述
    可以看到每隔十秒执行一次。

  • 相关阅读:
    CUDA 编程基础
    LeetCode581+621+207
    电源效率测试标准你知道多少?纳米软件带您了解
    支持向量机
    01 OSI七层网络排查 troubleshooting 思路及对应工具
    洛谷千题详解 | P1015 [NOIP1999 普及组] 回文数【C++、Java、Python语言】
    小程序实现下拉刷新
    重绘、重排区别如何避免
    ESP8266-Arduino编程实例-DHT11传感器数据储存到SD卡
    acwing算法提高之图论--最小生成树的典型应用
  • 原文地址:https://blog.csdn.net/Cavewang/article/details/126197742