springboot整合quartz定时任务

本文介绍如何在SpringBoot框架中整合Quartz实现定时任务。通过导入必要的依赖,配置Quartz参数,创建任务抽象类、任务工厂、任务管理器及具体任务,最终在Controller中调用任务。涉及SpringBoot、Quartz、依赖管理、任务调度等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天介绍一下springboot框架整合quartz。

首先导入依赖,注意:一下依赖缺一不可

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

接下来创建quartz的配置文件

# 固定前缀org.quartz
# 主要分为scheduler、threadPool、jobStore、plugin等部分
#
#
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

# threadCount和threadPriority将以setter的形式注入ThreadPool实例
# 并发个数
org.quartz.threadPool.threadCount = 5
# 优先级
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 5000

# 默认存储在内存中
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

#持久化
#org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.tablePrefix = QRTZ_
#org.quartz.jobStore.dataSource = qzDS
#org.quartz.dataSource.qzDS.driver = com.mysql.cj.jdbc.Driver
#org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartz?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
#org.quartz.dataSource.qzDS.user = root
#org.quartz.dataSource.qzDS.password = 19970121
#org.quartz.dataSource.qzDS.maxConnections = 10

接着创建一下三个类

import org.quartz.Job;
import org.quartz.JobExecutionContext;

public abstract class AbstractTask implements Job {

    protected abstract void executeInternal(JobExecutionContext context);

    protected String cronExpression;

    @Override
    public void execute(JobExecutionContext context) {
        try {
            executeInternal(context);
        } catch (Exception e) {
        }
    }

    public String getCronExpression() {
        return cronExpression;
    }

}
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;

@Component
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        final Object jobInstance = super.createJobInstance(bundle);
        beanFactory.autowireBean(jobInstance);
        return jobInstance;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
    }
}
package com.example.reader.quartz;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@Scope("singleton")
public class QuartzManager implements ApplicationContextAware {

    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

    private static final String JOB_DEFAULT_GROUP_NAME = "JOB_DEFAULT_GROUP_NAME";

    private static final String TRIGGER_DEFAULT_GROUP_NAME = "TRIGGER_DEFAULT_GROUP_NAME";

    private ApplicationContext applicationContext;

    private Scheduler scheduler;

    @Autowired
    private AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory;

    public void start() {
        //启动所有任务
        try {
            this.scheduler = schedulerFactory.getScheduler();
            scheduler.setJobFactory(autowiringSpringBeanJobFactory);
            //启动所有任务,这里获取AbstractTask的所有子类
            Map<String, AbstractTask> tasks = applicationContext.getBeansOfType(AbstractTask.class);
            tasks.forEach((k, v) -> {
                String cronExpression = v.getCronExpression();
                if (cronExpression != null) {
                    addJob(k, v.getClass().getName(), cronExpression);
                }
            });
        } catch (SchedulerException e) {
            throw new RuntimeException("init Scheduler failed");
        }
    }

    public boolean addJob(String jobName, String jobClass, String cronExp) {
        boolean result = false;
        if (!CronExpression.isValidExpression(cronExp)) {
            return result;
        }
        try {
            JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_DEFAULT_GROUP_NAME))
                    .ofType((Class<Job>) Class.forName(jobClass))
                    .build();
            Trigger trigger = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                    .withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (Exception e) {
        }
        result = true;
        return result;
    }

    public boolean updateJob(String jobName, String cronExp) {
        boolean result = false;
        if (!CronExpression.isValidExpression(cronExp)) {
            return result;
        }
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME);
        try {
            if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                Trigger newTrigger = TriggerBuilder.newTrigger()
                        .forJob(jobDetail)
                        .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                        .withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
                        .build();
                scheduler.rescheduleJob(triggerKey, newTrigger);
                result = true;
            } else {
            }
        } catch (SchedulerException e) {
        }
        return result;
    }

    public boolean deleteJob(String jobName) {
        boolean result = false;
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        try {
            if (scheduler.checkExists(jobKey)) {
                result = scheduler.deleteJob(jobKey);
            } else {
            }
        } catch (SchedulerException e) {
        }
        return result;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

最后,创建一个任务

import com.example.reader.utils.util;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;

@Component("testTask")
public class TestTask extends AbstractTask {
    util ut = new util();
    @Override
    protected void executeInternal(JobExecutionContext context) {
        System.out.println("任务开启++");
        ut.reader();//此处写任务,大家可以用输出语句进行测试
        System.out.println("任务结束");
    }
}

下面是controller

 @RequestMapping("/readdate")
    public String testCronTest(String date)  {
        String flag = "";
        String cron = du.getCron(date);
       /* TimeUnit.SECONDS.sleep(10);
        //修改任务
        quartzManager.updateJob("testTask", "0/3 * * * * ? ");
        //删除任务
        quartzManager.deleteJob("testTask");
        *///添加任务
        quartzManager.start();
         //cron = "0/1 * * * * ?";
        boolean testTask = quartzManager.addJob("testTask",             
        this.testTask.getClass().getName(), cron);
       /* //修改任务
        quartzManager.updateJob("testTask", "0/3 * * * * ?");
        //删除任务
        quartzManager.deleteJob("testTask");*/
        System.out.println(testTask);
        if(testTask == true){
           flag = "OK";
       }else{
           flag = "NO";
       }
         return JSON.toJSONString(flag);
    }
//我只使用了添加任务,大家有其他需求可以把注释去掉

 

### 集成Spring Boot与Quartz调度器框架 为了在Spring Boot项目中集成Quartz以实现定时任务,可以利用Spring提供的便捷类来支持Quartz,并减少应用程序与其他组件之间的耦合度[^1]。 #### 创建Spring Boot应用并引入依赖项 首先,在`pom.xml`文件中加入必要的Maven依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 这一步骤确保了项目的构建配置包含了运行所需的所有库和工具。 #### 定义Job类 接着定义一个实现了`Job`接口的任务执行逻辑。例如创建名为`MyJob.java`的Java源码如下所示: ```java import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Executing job at " + new java.util.Date()); } } ``` 这段代码展示了如何编写简单的作业处理程序,它会在每次触发时打印当前时间戳至控制台。 #### 设置计划表达式 通过配置文件或编程方式设置具体的调度策略。这里采用XML形式指定调度参数作为例子说明(实际开发推荐使用注解或者YAML/Properties格式)。编辑位于资源目录下的`scheduler-context.xml`: ```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Define the bean of our custom job --> <bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="app"/> <property name="targetMethod" value="printMessage"/> </bean> <!-- Configure a simple trigger that fires every five seconds --> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="myJobDetail"/> <property name="startDelay" value="0"/> <property name="repeatInterval" value="5000"/> </bean> <!-- Register the scheduler factory bean --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger"/> </list> </property> </bean> </beans> ``` 上述配置指定了每五秒重复一次的任务触发机制[^2]。 #### 启动应用程序 最后修改入口函数中的启动过程,加载自定义上下文环境变量: ```java package com.example.demo; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { // 加载包含quartz配置的应用上下文 new ClassPathXmlApplicationContext("scheduler-context.xml"); SpringApplication.run(DemoApplication.class, args); } } ``` 当调用此方法后,将会初始化Quartz调度服务实例并且按照预定的时间间隔持续循环执行已注册的工作单元直到进程终止为止[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值