通过SchedulingConfigurer 接口完成动态定时任务(配合数据库动态执行)

一、Spring 中,创建定时任务除了使用@Scheduled 注解外,还可以使用 SchedulingConfigurer。既然两者都可以实现定时任务,那有什么不同呢?

@Schedule注解的一个缺点就是其定时时间不能动态更改,它适用于具有固定任务周期的任务,若要修改任务执行周期,只能走“停服务→修改任务执行周期→重启服务”这条路。
而基于 SchedulingConfigurer 接口方式可以做到。SchedulingConfigurer 接口可以实现在@Configuration 类上,同时不要忘了,还需要@EnableScheduling 注解的支持。

二、如何使用

1、创建数据库表

CREATE TABLE `trip_job_lock`  (
  `job_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '定时任务名称',
  `is_lock` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '是否开启任务 1-开启,0-关闭',
  `job_cron` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务执行时间间隔',
  `job_desc` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务中午描述',
  PRIMARY KEY (`job_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '定时任务配置表' ROW_FORMAT = Dynamic;

INSERT INTO `trip_job_lock` VALUES ('1', NULL, '0/5 * * * * ?', NULL);

2、SchedulingConfigurer接口

(实现SchedulingConfigurer接口重写configureTasks方法)
package org.springframework.scheduling.annotation;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@FunctionalInterface
public interface SchedulingConfigurer {
    void configureTasks(ScheduledTaskRegistrar var1);
}

ScheduledTaskRegistrar类的几个方法
在这里插入图片描述
方法包含定时任务,延时任务,基于 Cron 表达式的任务,以及 Trigger 触发的任务。

3、具体实现

(1)Mapper接口

public interface JobMapper {

    @Select("<script>SELECT is_lock FROM trip_job_lock WHERE job_name = #{jobName}</script>")
    public String getIsLock(String jobName);

    @Select("<script>SELECT job_cron FROM trip_job_lock WHERE job_name = #{jobName}</script>")
    public String getCron(String jobName);
}




(2)定时任务实现SchedulingConfigurer接口

@Component
@SuppressWarnings("all")
@Slf4j
@EnableScheduling
@Configuration
public class AirTicketSettlementScheduler implements SchedulingConfigurer {

    @Resource
    private AirTicketSettlementTaskService airTicketSettlementTaskService;
    
    @Resource
    CtripUtil ctripUtil;

    @Autowired
    SnowFlake snowFlake;

    @Autowired
    ScheduledByRedisIP scheduledByRedisIP;

    @Autowired
    LogRecordService logRecordService;

    //飞机结算的url
    @Value("${FlightSettlementURL}")
    private String FlightSettlementURL;

    @Resource
    JobMapper jobMapper;
    
	@Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
            //1.添加任务内容(Runnable)
            () -> //System.out.println("执行定时任务2: " + LocalDateTime.now().toLocalTime()),
                isScheduler(),
            //2.设置执行周期(Trigger)
            triggerContext -> {
                //2.1 从数据库获取执行周期
                String cron = jobMapper.getCron("AirTicketSettlementScheduler");
                //2.2 合法性校验.
                if (StringUtils.isEmpty(cron)) {
                    // Omitted Code ..
                }

                //2.3 返回执行周期(Date)
                return new CronTrigger(cron).nextExecutionTime(triggerContext);
            }
        );
    }

    //判断定时任务是否已关闭
    public void isScheduler(){
        String isLock = jobMapper.getIsLock("AirTicketSettlementScheduler");
        if("1".equals(isLock)) {
            updateAirSettlementTask();
        }else{
            log.info("机票结算数据入库定时任务已关闭!");
        }
    }

	private void updateAirSettlementTask() {
			//定时任务需要执行的任务
			..............
	}
}
  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是详细的步骤: 1. 首先,我们需要在pom.xml中添加Quartz的依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> ``` 2. 创建一个Job类,继承QuartzJobBean,并实现executeInternal方法。该方法就是我们要执行的任务逻辑。 ``` public class MyJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // 任务逻辑 } } ``` 3. 创建一个实现SchedulingConfigurer接口定时任务配置类。该类中可以动态添加定时任务,也可以从数据库配置文件等读取定时任务。 ``` @Configuration public class QuartzConfig implements SchedulingConfigurer { @Autowired private ApplicationContext applicationContext; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { // 从数据库配置文件中读取定时任务 // ... // 动态添加定时任务 taskRegistrar.addTriggerTask( () -> { MyJob myJob = applicationContext.getBean(MyJob.class); myJob.executeInternal(null); }, triggerContext -> { // 定时任务表达式 CronTrigger cronTrigger = new CronTrigger("0/5 * * * * ?"); return cronTrigger.nextExecutionTime(triggerContext); } ); } } ``` 4. 在Spring Boot主类上加上@EnableScheduling注解,启用定时任务。 ``` @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 这样,我们就可以使用QuartzJobBean+SchedulingConfigurer实现动态添加定时任务了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值