在SpringBoot中使用Quartz实现动态调整间隔的自动任务
用SpringBoot + Quartz实现按时间间隔发送消息
完全可以实现这个需求,以下是具体的实现步骤和代码示例:
1. 添加Quartz依赖
在你的pom.xml(Maven)中添加SpringBoot的Quartz starter:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
如果用Gradle,就在build.gradle里加:
implementation 'org.springframework.boot:spring-boot-starter-quartz'
2. 创建消息发送Job
这个Job负责实际发送消息,通过JobDataMap接收要发送的消息内容:
import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MessageSendJob implements Job { private static final Logger logger = LoggerFactory.getLogger(MessageSendJob.class); @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 从JobDataMap中获取消息内容 String message = context.getJobDetail().getJobDataMap().getString("message"); logger.info("发送消息: {}", message); // 这里替换成你的实际发送逻辑,比如调用短信/邮件接口 // sendMessage(message); } }
3. 编写调度服务类
这个类负责初始化消息列表、发送第一条消息,然后计算间隔时间调度第二个Job:
import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; import java.util.List; @Service public class MessageSchedulerService { @Autowired private Scheduler scheduler; public void scheduleMessages(List<String> messages, long delayMinutes) throws SchedulerException { // 1. 立即发送第一条消息(也可以用Quartz调度立即执行) sendImmediateMessage(messages.get(0)); // 2. 计算第二条消息的执行时间:当前时间 + 间隔分钟数 LocalDateTime executeTime = LocalDateTime.now().plusMinutes(delayMinutes); Date triggerTime = Date.from(executeTime.atZone(ZoneId.systemDefault()).toInstant()); // 3. 调度第二条消息的Job JobDetail jobDetail = JobBuilder.newJob(MessageSendJob.class) .withIdentity("secondMessageJob", "messageGroup") .usingJobData("message", messages.get(1)) .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("secondMessageTrigger", "messageGroup") .startAt(triggerTime) .build(); scheduler.scheduleJob(jobDetail, trigger); } private void sendImmediateMessage(String message) { // 直接执行发送逻辑,或者也可以用Quartz调度一个立即执行的Job System.out.println("立即发送消息: " + message); // 实际发送逻辑 // sendMessage(message); } }
4. 测试调度逻辑
在启动类或者Controller中调用这个服务:
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import java.util.List; @SpringBootApplication public class QuartzMessageApplication { public static void main(String[] args) { SpringApplication.run(QuartzMessageApplication.class, args); } @Bean public CommandLineRunner run(MessageSchedulerService schedulerService) { return args -> { // 模拟消息列表和间隔时间(21分钟) List<String> messages = List.of("hello", "how are you"); long delayMinutes = 21; schedulerService.scheduleMessages(messages, delayMinutes); }; } }
关键说明
- 如果消息列表不止2条,可以循环处理:发送当前消息后,计算与下一条的间隔,调度下一个Job,以此类推。
JobDataMap可以传递更多参数,比如消息ID、接收人等,只要是可序列化的对象都可以放进去。- 如果你需要持久化Quartz的任务(比如服务重启后不丢失),可以在
application.properties中配置Quartz的存储方式,比如用数据库:
spring.quartz.job-store-type=jdbc spring.quartz.jdbc.initialize-schema=always
内容的提问来源于stack exchange,提问作者Caos Develop
相关产品推荐
相关产品推荐

