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
浙公网安备 33010602011771号