
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for my_task_corn
-- ----------------------------
DROP TABLE IF EXISTS `my_task_corn`;
CREATE TABLE `my_task_corn` (
`corn_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`corn` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 'corn表达式',
`execute_cycle` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '定时任务执行的配置的周期(01:每天一次 02:每周一次 03:每月一次)',
`corn_desc` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '解释说明',
`off_state` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '关闭状态',
PRIMARY KEY (`corn_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '定时任务配置表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of my_task_corn
-- ----------------------------
INSERT INTO `my_task_corn` VALUES (1, '0/5 * * * * ?', '00', '每5秒执行一次', 'on');
INSERT INTO `my_task_corn` VALUES (2, '0 0 0 * * ? ', '01', '每天一次,每天晚上凌晨24点执行(0 0 0 * * ? *)', 'on');
INSERT INTO `my_task_corn` VALUES (3, '0 0 0 ? * 5', '02', '每周一次,每周五凌晨24点执行', 'off');
INSERT INTO `my_task_corn` VALUES (4, '0 0 0 1 * ?', '03', '每月1号执行凌晨24点执行', 'off');
INSERT INTO `my_task_corn` VALUES (6, '0 0 0 1 7 ?', '04', '每年一次,每年的7月1日执行凌晨24点执行', 'on');
SET FOREIGN_KEY_CHECKS = 1;
package com.liu.susu.pojo;
import javax.persistence.*;
import java.util.Objects;
/**
* @FileName MyTaskCornEntity
* @Description 动态定时任务配置表
* @Author susu
* @date 2022-06-21
**/
@Entity
@Table(name = "my_task_corn", schema = "liu", catalog = "")
public class MyTaskCornEntity {
private int cornId;
private String corn;
private String executeCycle;
private String cornDesc;
private String offState;
@Id
@Column(name = "corn_id", nullable = false)
public int getCornId() {
return cornId;
}
public void setCornId(int cornId) {
this.cornId = cornId;
}
@Basic
@Column(name = "corn", nullable = true, length = 32)
public String getCorn() {
return corn;
}
public void setCorn(String corn) {
this.corn = corn;
}
@Basic
@Column(name = "execute_cycle", nullable = true, length = 4)
public String getExecuteCycle() {
return executeCycle;
}
public void setExecuteCycle(String executeCycle) {
this.executeCycle = executeCycle;
}
@Basic
@Column(name = "corn_desc", nullable = true, length = 100)
public String getCornDesc() {
return cornDesc;
}
public void setCornDesc(String cornDesc) {
this.cornDesc = cornDesc;
}
@Basic
@Column(name = "off_state", nullable = true, length = 10)
public String getOffState() {
return offState;
}
public void setOffState(String offState) {
this.offState = offState;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyTaskCornEntity that = (MyTaskCornEntity) o;
return cornId == that.cornId && Objects.equals(corn, that.corn) && Objects.equals(executeCycle, that.executeCycle) && Objects.equals(cornDesc, that.cornDesc) && Objects.equals(offState, that.offState);
}
@Override
public int hashCode() {
return Objects.hash(cornId, corn, executeCycle, cornDesc, offState);
}
}

package com.liu.susu.thread.task.scheduled.dynamic;
import com.liu.susu.pojo.Dog;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
* @FileName CornUtils
* @Description
* @Author susu
* @date 2022-06-21
**/
@Service
public class CornUtils {
@PersistenceContext
private EntityManager entityManager;
public String getCorn(String executeCycle){
String sql = "select t.corn from my_task_corn t where t.execute_cycle=?1";
Query query = entityManager.createNativeQuery(sql);
query.setParameter(1,executeCycle);
return (String) query.getSingleResult();
}
}
如下:

package com.liu.susu.thread.task.scheduled.dynamic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @FileName DynamicScheduledTest
* @Description 动态定时任务(从数据库获取配置)
* @Author susu
* @date 2022-06-21
**/
@Component
@Slf4j
public class DynamicScheduledTest implements SchedulingConfigurer {
@Autowired
private CornUtils cornUtils;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> log.info("这里动态执行定时任务--->"+Thread.currentThread().getName()),
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取 corn 表达式(执行周期)
String cron = cornUtils.getCorn("00");
log.info("cron表达式--->: " + cron);
//2.3 返回执行周期(Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}

package com.liu.susu.thread.task.scheduled.dynamic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @FileName DynamicScheduledTest
* @Description 动态定时任务(从数据库获取配置)
* @Author susu
* @date 2022-06-21
**/
@Component
@Slf4j
public class DynamicScheduledTest2 implements SchedulingConfigurer {
@Autowired
private CornUtils cornUtils;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addTriggerTask(myTask(),trigger());
}
/**
* 要执行的定时任务内容
* @return
*/
private Runnable myTask() {
return new Runnable() {
@Override
public void run() {
//业务逻辑部分
log.info("这里动态执行定时任务--->"+Thread.currentThread().getName());
}
};
}
/**
* 从数据库读取执行周期
* @return
*/
private Trigger trigger() {
return new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
//每一次任务触发,都会执行这里的方法一次,重新获取下一次的执行时间。所以它是下下次才生效的,即不是实时生效
//1.从数据库获取 corn 表达式(执行周期)
String cron = cornUtils.getCorn("00");
log.info("cron表达式--->: " + cron);
//2 返回执行周期(Date)
CronTrigger cronTrigger = new CronTrigger(cron);
Date date = cronTrigger.nextExecutionTime(triggerContext);
return date;
}
};
}
}


package com.liu.susu.thread.task.scheduled.dynamic;
import com.liu.susu.pojo.MyTaskCornEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
/**
* @FileName DynamicScheduledTest
* @Description 动态定时任务(从数据库获取配置)——多个任务
* @Author susu
* @date 2022-06-21
**/
@Component
@Slf4j
public class DynamicScheduledTest3 implements SchedulingConfigurer {
@Autowired
private CornUtils cornUtils;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
//1.获取需要执行的所有的任务
List<MyTaskCornEntity> cronList = cornUtils.getAllCornsList();
//2.根据配置情况执行对应的任务
for (MyTaskCornEntity cornEntity : cronList){
scheduledTaskRegistrar.addTriggerTask(myTask(cornEntity),myTrigger(cornEntity));
}
}
/**
* 这里执行所有的定时任务
* @param cornEntity
* @return
*/
private Runnable myTask(MyTaskCornEntity cornEntity) {
return new Runnable() {
@Override
public void run() {
//业务逻辑部分
if ("00".equals(cornEntity.getExecuteCycle())){
log.info("这里动态执行的定时任务是--->"+cornEntity.getCorn()+"-->"+Thread.currentThread().getName());
}else if ("05".equals(cornEntity.getExecuteCycle())){
log.info("这里动态执行的定时任务是--->"+cornEntity.getCorn()+"-->"+Thread.currentThread().getName());
}
}
};
}
/**
* 根据每一个配置的cron表达式,返回执行周期
* @param cornEntity
* @return
*/
private Trigger myTrigger(MyTaskCornEntity cornEntity){
return new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
CronTrigger trigger = new CronTrigger(cornEntity.getCorn());
return trigger.nextExecutionTime(triggerContext);
}
};
}
}




package com.liu.susu.thread.task.scheduled.dynamic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @FileName DynamicScheduledPoolConfig
* @Description 动态定时任务的线程池
* @Author susu
* @date 2022-03-09
**/
@Configuration
public class DynamicScheduledPoolConfig {
private static int poolSize = 5;//核心线程
private static int awaitTermination = 60;//挂壁时间
private static String threadNamePrefix = "task-job-";
private static volatile ThreadPoolTaskScheduler taskScheduler;
@Bean
public static Executor getMySchedulerPool(){
if(taskScheduler == null){
synchronized (ThreadPoolTaskScheduler.class){
if(taskScheduler == null){
taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setThreadNamePrefix(threadNamePrefix);
taskScheduler.setPoolSize(poolSize);
// taskScheduler.setThreadFactory(Executors.defaultThreadFactory());
taskScheduler.setAwaitTerminationSeconds(awaitTermination);//演示挂壁的时间为60s
/**设置为false,关闭线程池中的任务时,直接执行shutdownNow() 延时关闭 开启*/
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//线程池对拒绝任务(无线程可用的)的处理策略
taskScheduler.initialize();//初始化
}
}
}
return taskScheduler;
}
}
package com.liu.susu.thread.task.scheduled.dynamic;
import com.liu.susu.pojo.MyTaskCornEntity;
import com.liu.susu.thread.task.async.async2.config.LiuTaskExecutorConfig2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @FileName DynamicScheduledTest
* @Description 动态定时任务(从数据库获取配置)——多个任务
* @Author susu
* @date 2022-06-21
**/
@Component
@Slf4j
public class DynamicScheduledTest4 implements SchedulingConfigurer {
@Autowired
private CornUtils cornUtils;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
//0-1: 配置线程池
// scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
//0-2: 用自定义的线程池
scheduledTaskRegistrar.setScheduler(DynamicScheduledPoolConfig.getMySchedulerPool());
//1.获取需要执行的所有的任务
List<MyTaskCornEntity> cronList = cornUtils.getAllCornsList();
//2.根据配置情况执行对应的任务
for (MyTaskCornEntity cornEntity : cronList){
scheduledTaskRegistrar.addTriggerTask(myTask(cornEntity),myTrigger(cornEntity));
}
}
/**
* 这里执行所有的定时任务
* @param cornEntity
* @return
*/
private Runnable myTask(MyTaskCornEntity cornEntity) {
return new Runnable() {
@Override
public void run() {
//业务逻辑部分
// log.info("这里动态执行的定时任务是--->"+cornEntity.getCorn()+"-->"+Thread.currentThread().getName());
if ("00".equals(cornEntity.getExecuteCycle())){
log.info("任务1:这里动态执行的定时任务是--->"+cornEntity.getCorn()+"-->"+Thread.currentThread().getName());
}else if ("05".equals(cornEntity.getExecuteCycle())){
log.info("任务2:这里动态执行的定时任务是--->"+cornEntity.getCorn()+"-->"+Thread.currentThread().getName());
}
}
};
}
/**
* 根据每一个配置的cron表达式,返回执行周期
* @param cornEntity
* @return
*/
private Trigger myTrigger(MyTaskCornEntity cornEntity){
return new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
CronTrigger trigger = new CronTrigger(cornEntity.getCorn());
return trigger.nextExecutionTime(triggerContext);
}
};
}
}
