浅谈在springboot中使用定时任务的方式

网友投稿 248 2023-01-01

浅谈在springboot中使用定时任务的方式

springboot定时任务

在springboot环境下有多种方法,这里记录下使用过的其中两种;1、使用注解,2、通过实现接口的方式。

使用注解的方式虽然比较简单,但是如果项目需要用户对定时周期进行修改操作,只使用注解就比较难实现。所以可以使用实现接口的方式。通过对接口的实现,可以在项目运行时根据需要修改任务执行周期,只需要关闭原任务再开启新任务即可。

1、使用注解方式

​ 首先需要在启动类下添加 @EnableScheduling 注解(@EnableAsync是开启异步的注解)

package com.fongtech.cli;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication

@MapperScan("com.fongtech.cli.mbg.*.**")

@EnableAsync

@EnableScheduling

public class SpringbootAdminApplication {

public static void main(String[] args) {

SpringApplication.run(SpringbootAdminApplication.class, args);

}

}

接着在需要用到定时任务的类和方法下加 @Component 和 @Scheduled(cron = "0 0/1 * * * ? ")注解,其中@Scheduled()中的 ‘cron' 有固定的格式。(@Async注解表示开启异步)

@Slf4j

@Component

public class AsyncTaskConfiguration {

/**

* 每分钟检查任务列表,判断任务类型执行相应的任务

* 根据实际任务执行情况,限定执行任务数量

*/

@Scheduled(cron = "0 0/1 * * * ? ")

@Async

public void startCommonTask() throws Exception {

log.info("startCommonTask start........." + Thread.currentThread().getName());

commonTaskService.startCommonTask();

log.info("startCommonTask end........." + Thread.currentThread().getName());

}}

2、使用实现接口的方式

​ 通过实现 SchedulingConfigurer 接口,可对定时任务进行操作。实现接口的方式相比使用注解更加灵活,但需要编写代码,相对繁琐。

​ 实现工具类如下:

package com.fongtech.cli.admin.tasktime;

import com.fongtech.cli.common.util.BeanUtils;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.SchedulingException;

import org.springframework.scheduling.TaskScheduler;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.scheduling.annotation.SchedulingConfigurer;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import org.springframework.scheduling.config.TriggerTask;

import org.springframework.scheduling.support.CronTrigger;

import javax.annotation.PostConstruct;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ScheduledFuture;

/**

* @author linb

* @date 2020/6/15 11:16

*/

@Configuration

//@EnableScheduling

public class DefaultSchedulingConfigurer implements SchedulingConfigurer {

private ScheduledTaskRegistrar taskRegistrar;

private Set> scheduledFutures = null;

private Map> taskFutures = new ConcurrentHashMap<>();

@Override

public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

this.taskRegistrar = taskRegistrar;

}

@SuppressWarnings("unchecked")

private Set> getScheduledFutures() {

if (scheduledFutures == null) {

try {

// spring版本不同选用不同字段scheduledFutures

scheduledFutures = (Set>) BeanUtils.getProperty(taskRegistrar, "scheduledTasks");

} catch (NoSuchFieldException e) {

throw new SchedulingException("not found scheduledFutures field.");

}

}

return scheduledFutures;

}

/**

* 添加任务

*/

public void addTriggerTask(String taskId, TriggerTask triggerTask) {

if (taskFutures.containsKey(taskId)) {

throwRyMnOq new SchedulingException("the taskId[" + taskId + "] was added.");

}

TaskScheduler scheduler = taskRegistrar.getScheduler();

ScheduledFuture> future = scheduler.schedule(triggerTask.getRunnable(), triggerTask.getTrigger());

getScheduledFutures().add(future);

taskFutures.put(taskId, future);

}

/**

* 取消任务

*/

public void cancelTriggerTask(String taskId) {

ScheduledFuture> future = taskFutures.get(taskId);

if (future != null) {

future.cancel(true);

}

taskFutures.remove(taskId);

getScheduledFutures().remove(future);

}

/**

* 重置任务

*/

public void resetTriggerTask(String taskId, TriggerTask triggerTask) {

cancelTriggerTask(taskId);

addTriggerTask(taskId, triggerTask);

}

/**

* 任务编号

*/

public Set taskIds() {

return taskFutures.keySet();

}

/**

* 是否存在任务

*/

public boolean hasTask(String taskId) {

return this.taskFutures.containsKey(taskId);

}

/**

* 任务调度是否已经初始化完成

*/

public boolean inited() {

return this.taskRegistrar != null && this.taskRegistrar.getScheduler() != null;

}

}

​ 在项目启动后就自动开启任务的操作类如下:

package com.fongtech.cli.admin.tasktime;

import com.fongtech.cli.admin.service.IAuthLoginService;

import com.fongtech.cli.admin.service.IBackupsService;

import com.fongtech.cli.admin.service.IDictionnaryEntryService;

import com.fongtech.cli.mbg.model.entity.AuthLogin;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.CommandLineRunner;

import org.springframework.core.annotation.Order;

import org.springframework.scheduling.config.TriggerTask;

import org.springframework.scheduling.support.CronTrigger;

import org.springframework.stereotype.Component;

/**

* 项目启动后执行,

*/

@Slf4j

@Component

@Order(value = 1)

public class CmdRunner implements CommandLineRunner {

@Autowired

private DefaultSchedulingConfigurer defaultSchedulingConfigurer;

@Autowired

private IDictionnaryEntryService dictionnaryEntryService;

@Autowired

private IBackupsService backupsService;

@Autowired

private IAuthLoginService authLoginService;

@Override

public void run(String... args) throws Exception {

log.info("------按照预设备份周期启动数据库备份定时任务");

while (!defaultSchedulingConfigurer.inited())

{

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

}

}

String cron = dictionnaryEntryService.getEntryValueByName("CRON_VALUE");

//默认按照管理员用户权限执行备份任务

AuthLogin authLogin = authLoginService.query().eq(AuthLogin::getLogin_user, "admin").getOne();

//启动线程,按照原表内的时间执行备份任务

defaultSchedulingConfigurer.addTriggerTask("task",

new TriggerTask(

() -> System.out.println("=====----------启动定时任务=-----------");,

new CronTrigger(cron)));

}

}

​ 暂停定时任务:

defaultSchedulingConfigurer.cancelTriggerTask("task");

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:邮政单快递物流查询单号查询(邮政快递单号查询询单号查询)
下一篇:网站api接口 干什么的(api接口是干嘛的)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~