软件编程
位置:首页>> 软件编程>> java编程>> 浅谈在springboot中使用定时任务的方式

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

作者:拍打醒  发布时间:2023-03-02 19:14:09 

标签: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<ScheduledFuture<?>> scheduledFutures = null;
   private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<>();

@Override
   public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
       this.taskRegistrar = taskRegistrar;
   }

@SuppressWarnings("unchecked")
   private Set<ScheduledFuture<?>> getScheduledFutures() {
       if (scheduledFutures == null) {
           try {
               // spring版本不同选用不同字段scheduledFutures
               scheduledFutures = (Set<ScheduledFuture<?>>) 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)) {
           throw 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<String> 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");

来源:https://blog.csdn.net/iampatrick_star/article/details/117930163

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com