SpringBoot设置动态定时任务

一、说明

1.在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置。

2.定时任务执行时间可根据数据库中某个设置字段动态改变。

二、maven依赖

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</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-context-support</artifactId>
</dependency>

三、代码

1.输出测试类

import org.quartz.JobExecutionException;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component; @Component
@Configuration
@EnableScheduling
public class ScheduledJob { public void execute() throws JobExecutionException { System.out.println("hahaha");
} }

ScheduledJob

2.Quartz配置类

import org.quartz.Trigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean; @Configuration
public class QuartzConfigration {
/**
* attention:
* Details:配置定时任务
*/
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledJob task) {// ScheduleTask为需要执行的任务
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否并发执行
* 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
* 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
*/
jobDetail.setConcurrent(false); jobDetail.setName("srd-chhliu");// 设置任务的名字
jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 /*
* 为需要执行的实体类对应的对象
*/
jobDetail.setTargetObject(task); /*
* sayHello为需要执行的方法
* 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法
*/
jobDetail.setTargetMethod("execute");
return jobDetail;
} /**
* attention:
* Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
*/
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
tigger.setJobDetail(jobDetail.getObject());
tigger.setCronExpression("0 10 15 * * ?");// 初始时的cron表达式
tigger.setName("srd-chhliu");// trigger的name
return tigger; } /**
* attention:
* Details:定义quartz调度工厂
*/
@Bean(name = "schedulerTwo")
public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
bean.setOverwriteExistingJobs(true);
// 延时启动,应用启动1秒后
bean.setStartupDelay(1);
// 注册触发器
bean.setTriggers(cronJobTrigger);
return bean;
}
}

3.定时请求数据库获取时间类 注意sql语句的更改及判断 查询频率可自行更改

package com.jdkeji.shares.quartz;

import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import com.jdkeji.shares.config.model.BusinessConfig; @Configuration
@EnableScheduling
@Component
public class ScheduleRefreshDatabase {
@Autowired
private SqlSessionTemplate st; @Resource(name = "jobDetail")
private JobDetail jobDetail; @Resource(name = "jobTrigger")
private CronTrigger cronTrigger; @Resource(name = "schedulerTwo")
private Scheduler scheduler; @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务
public void scheduleUpdateCronTrigger() throws SchedulerException {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
String currentCron = trigger.getCronExpression();// 当前Trigger使用的
BusinessConfig bc = st.selectOne("BusinessConfig.selectByExample");
System.out.println(currentCron); String [] date = bc.getClxg().split(":");
String cron = "0 " + date[1] + " " + date[0] + " * * ?";
System.out.println(cron);
if (currentCron.equals(cron)) {
// 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
} else {
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// 按新的cronExpression表达式重新构建trigger
trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
.withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
currentCron = cron;
}
}
}

四、注意

QuartzConfigration类中的detailFactoryBean(ScheduledJob)

ScheduledJob就是我们的输出测试类

springboot动态定时任务的更多相关文章

  1. SpringBoot中并发定时任务的实现、动态定时任务的实现(看这一篇就够了)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10659045.html,否则将追究法律责任!!! 一.在JAVA开发领域,目前可以通过以下 ...

  2. springboot和quartz整合实现动态定时任务(持久化单节点)

    Quartz是一个完全由java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,它支持定时任务持久化到数据库,从而避免了重启服务器时任务丢失,支持分布式多节点,大大的 ...

  3. SpringBoot系列——动态定时任务

    前言 定时器是我们项目中经常会用到的,SpringBoot使用@Scheduled注解可以快速启用一个简单的定时器(详情请看我们之前的博客<SpringBoot系列--定时器>),然而这种 ...

  4. 【记录】【springboot】动态定时任务ScheduledFuture,可添加、修改、删除

    这里只演示添加和删除任务的,因为修改就是删除任务再添加而已. 方便演示,任务就是每3秒打印 1.没有任务 后台 2.添加一个任务 3.再添加一个任务 4.删除一个任务 5.再添加一个任务 6.代码 运 ...

  5. 玩转SpringBoot之定时任务详解

    序言 使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式: 一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer) 前者相信大家都很熟悉, ...

  6. SpringBoot的定时任务

    springBoot定时任务可分为多线程和单线程,而单线程又分为注解形式,接口形式 1.基于注解形式 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影 ...

  7. Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)

    什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定).      这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户 ...

  8. SpringBoot 配置定时任务

    SpringBoot启用定时任务,其内部集成了成熟的框架,因此我们可以很简单的使用它. 开启定时任务 @SpringBootApplication //设置扫描的组件的包 @ComponentScan ...

  9. springboot动态修改日志级别+权限认证

    1. springboot动态修改日志级别+权限认证 1.1. 需求 网上找到的动态修改日志级别的方式,基本都是没有权限验证的,或者特地关闭权限验证,但也没给出加上验证的解决方式 修改日志等级也是一个 ...

随机推荐

  1. 【数据库】通过触发器实现审计日志记录-demo篇

      触发器实现审计日志记录(记录增.删.改) #创建测试表 CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, ...

  2. idou老师教你学Istio 07: 如何用istio实现请求超时管理

    在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过一个简 ...

  3. sql 发生死锁

    SELECT request_session_id spid , OBJECT_NAME(resource_associated_entity_id) tableName FROM sys.dm_tr ...

  4. 算法笔记--BSGS && exBSGS 模板

    https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...

  5. #使用Python的turtle绘制正六边形、叠边形

    1.#Python的turtle绘制正六边形 代码: len=100 #表示边长像素 import turtle as t #正六边形内角都是120度,外角60度 for i in range(6): ...

  6. docker部署项目,对镜像,容器的操作

    服务器上的项目访问不了,所以我去看了看容器,果然 那我就删除容器呗 :docker rm 容器id docker rm f097e24a9a0f 说明:从镜像到容器,同一个镜像构建多个运行的 Dock ...

  7. 2014年9月9日 高级命令command的使用(上)

    上次说到了菜单 工具条按钮 上下文菜单都已经改为用command的方式去做了,这次稍微详细地说说. 在command的实现拓展点handler上右键,可以看到有enabledWhen,activeWh ...

  8. [Google Guava] 6-字符串处理:分割,连接,填充

    原文链接 译文链接 译者:沈义扬,校对:丁一 连接器[Joiner] 用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦.如果字符串序列中含有null,那连接操作会更难.Fluent风格的Joine ...

  9. javascript---操作节点

    快捷键:jiedian(节点) 节点增删改appendChild() insertBefore() replaceNode() <!DOCTYPE html><html lang=& ...

  10. python 实践--新闻聚合

    采集新闻,体会到面向问题和面向对象的区别. 如果希望新闻来源多出,比如NNTP,Web.可以实现:Source,Destination,NewItem,NewAgent. Scoure处理来源, De ...