SpringBoot添加定时任务

 

背景描述: 需要定期执行一批数据 ,所以就需要定义定时任务啦

 

一、固定的定时任务类:(修改定时任务执行时间时需要重启服务)

package com.gaunyi.batteryonline.web.scheduled;

import com.gaunyi.batteryonline.service.OnePartnerContactsAbstract;
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;

/**
 * 定时任务类
 */
@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class OnePartnerScheduled {

    @Autowired
    private OnePartnerContactsAbstract onePartnerAbstract;

   //定时任务 每3秒跑一次数
//    @Scheduled(cron = "0/3 * * * * ?")
//    private void configureTasksDemo() {
//        System.out.println("定时任务执行");
//    }

    //3.添加定时任务(每30分钟执行一次)
    @Scheduled(cron = "* 0/30 * * * ?")
    private void configureTasks() {
        dealContactOnelife();
    }

    public Integer dealContactOnelife(){
        Integer resultNums = null;
        try {
            resultNums = getContactOnelife();
        } catch(Exception e){
            System.out.println("数据获取失败,请注意检查,失败原因:"+ e);
            dealContactOnelife();//失败了就重新开始跑数
        }
        return resultNums;
    }

    private Integer getContactOnelife() throws Exception{

        long starttime = System.currentTimeMillis();
        //省略数据处理逻辑...
        long endtime = System.currentTimeMillis();
        System.out.println("整体方法耗时:"+(endtime-starttime)/1000 +"s");

        return contactsOnelife;
    }
}

  

二、定时任务执行时间可配置化,定义到数据库中(修改定时任务执行时间不需要重启服务)

数据库定时任务表设计( rs_cronConfig ):

DROP TABLE IF EXISTS `rs_cronConfig`;
CREATE TABLE `rs_cronConfig` (
  `SEQID` int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '数据库自增长唯一标识',
  `TASKNAME` varchar(128) NOT  NULL COMMENT '定时任务名称',
  `TASKCRON` varchar(32) NOT NULL COMMENT '定时任务执行时间-周期表达式',
  `STATUS` TINYINT DEFAULT 0 COMMENT '0-正常可使用,1-已弃用',
  `LASTUPDATETIME` datetime DEFAULT now() COMMENT '上一次更新时间',
  `CREATETIME` datetime DEFAULT now() COMMENT '数据创建时间',
  `REMARK` varchar(255) DEFAULT NULL COMMENT '备注信息'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=1 COMMENT='定时任务配置表';
 

 

插入与更新定时任务数据示例: 

insert into rs_cronConfig(TASKNAME,TASKCRON,REMARK) values('demoScheduledDynamic','* 0/30 * * * ?','示例数据定时任务-每30分钟执行一次');
update rs_cronConfig set TASKCRON='0/3 * * * * ?',LASTUPDATETIME=now(),REMARK='示例数据定时任务-每3秒钟执行一次' where TASKNAME='demoScheduledDynamic' AND STATUS=0;

 

定时任务执行示例(Java)  

package com.gaunyi.batteryonline.web.scheduled;

import com.gaunyi.batteryonline.service.OnePartnerContactsAbstract;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
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.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 定时任务类 动态配置的定时任务类
 */
@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class OnePartnerScheduledDynamic implements SchedulingConfigurer {

    @Autowired
    private OnePartnerContactsAbstract onePartnerAbstract;

//    @Scheduled(cron = "0/3 * * * * ?")
//    private void configureTasksDemo() {
//        System.out.println("定时任务执行");
//    }

    //3.添加定时任务
   /* @Scheduled(cron = "* 0/30 * * * ?")
    private void configureTasks() {
        dealContactOnelife();
    }*/

    @Mapper
    public interface CronMapper {
        @Select("select TASKCRON from rs_cronConfig where TASKNAME='demoScheduledDynamic' AND STATUS=0")
        public String getTaskCron();
    }

    @Autowired      //注入mapper
    @SuppressWarnings("all")
    CronMapper cronMapper;

    /**
     * 定时任务方法
     * @param taskRegistrar
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        System.out.println("进入定时任务方法");
        taskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> dealContactOnelife(),
                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1 从数据库获取执行周期
                    String cron = cronMapper.getTaskCron();
                    System.out.println("Cron:"+cron);
                    //2.2 合法性校验.
                    if (StringUtils.isEmpty(cron)) {
                        // Omitted Code ..
                        //CronExpression.isValidExpression(cron) 需要引入quartz的jar包
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }

    public Integer dealContactOnelife(){
        System.out.println("数据定时任务开始执行,开始时间:"+ LocalDateTime.now().toLocalTime());
        Integer resultNums = null;
        try {
            resultNums = getContactOnelife();
        } catch(Exception e){
            System.out.println("数据获取失败,请注意检查,失败原因:"+ e);
            dealContactOnelife();//失败了就重新开始跑数
        }
        return resultNums;
    }

    private Integer getContactOnelife() throws Exception{

        long starttime = System.currentTimeMillis();
        //中间省略数据处理逻辑...
        long endtime = System.currentTimeMillis();
        System.out.println("整体方法耗时:"+(endtime-starttime)/1000 +"s");

        return contactsOnelife;
    }


}

 

Lamada表达式实现Runnable接口示例:

参考博客地址:https://www.cnblogs.com/franson-2016/p/5593080.html

// 1.1使用匿名内部类  
new Thread(new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world !");  
    }  
}).start();  
  
// 1.2使用 lambda expression  
new Thread(() -> System.out.println("Hello world !")).start();  
  
// 2.1使用匿名内部类  
Runnable race1 = new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world !");  
    }  
};  
  
// 2.2使用 lambda expression  
Runnable race2 = () -> System.out.println("Hello world !");  
   
// 直接调用 run 方法(没开新线程哦!)  
race1.run();  
race2.run(); 

  

总结:

第一种定时任务的配置是固定的,写法简单容易上手,但是不够灵活,想要更改定时任务执行时间的时候需要修改代码重启服务(对于有可能会变动的任务不太推荐)

第二种定时任务的配置是从数据库里面读取的,比较推荐! 需要注意检查数据库中配置的定时任务格式。(推荐使用!!!)

 

 posted on 2020-03-19 11:16  阿叮339  阅读(594)  评论(0编辑  收藏  举报