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. Pytest编写测试函数

    Pytest编写测试函数 一个规范的测试方法一定带有断言,在使用pytest时,可以直接使用Python自带的assert关键字 Pytest允许在assert关键字添加任意表达式,表达式的值通过bo ...

  2. kafka相关

    一.消息队列优点(解耦.异步.削峰)二.用消息队列都有什么优点和缺点?三.kafka.activemq.rabbitmq.rocketmq都有什么区别四.如何保证消息队列的高可用啊?五.如何保证消息不 ...

  3. Linux 误卸载自带python后的解决办法

    1:卸载python(以免有些同学没有卸载干净) rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps #强制删除已安装程序及其关联 wher ...

  4. Nginx中ngx_http_auth_basic_moudel和ngx_http_stub_status_module模块

    ngx_http_auth_basic_module实现基于⽤用户的访问控制,使⽤用basic机制进⾏行行⽤用户认证指令:5.1 auth_basicSyntax: auth_basic string ...

  5. BZOJ 3589 动态树 (树链剖分+线段树)

    前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...

  6. 9、Spring Boot 2.x 集成 Thymeleaf

    1.9 Spring Boot 2.x 集成 Thymeleaf 完整源码: Spring-Boot-Demos 1.9.1 在pom中引入依赖 <dependency> <grou ...

  7. 【题解】Knight Moves-C++

    题目Description在一个8*8的棋盘上,一只中国象棋中的马要从一个点跳到另一个点.问最少需要多少步.Input整个测试组由多组数据组成,请做到文件底结束.对于每组数据,前两个坐标代表出发点,后 ...

  8. 002_FreeRTOS临界段代码

    (一)临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段 (二)FreeRTOS 与 临 界 段 代 码 保 护 有 关 的 函 数 有 4 个,两个是任务级的临界段代码保护,两个是中断 ...

  9. synchronized和AtomicXXX效率比较

    在Java中,i++和++i都是xian线程不安全的,如果要用十个线程累加一个资源,就会出现错误.synchronized和Atomic是实现线程安全常用方法.而二者效率问题孰优孰劣?本着规律符合任意 ...

  10. MySQL 热快问题解决

    原文地址:http://blog.itpub.net/22664653/viewspace-1269948 一  背景 某个业务线 商品开放开用户申请免费试用,当某个商品特别吸引人时,比如iPhone ...