SpringBoot实现定时任务的几种方式(常用)

1,929 阅读3分钟

第一种

使用自带的Scheduled,这相当于一个轻量级的Quartz,它可以让我们直接使用注解来完成定时任务的配置。
缺点定时任务在同一线程中串行执行,在多定时任务的需求下不适用
解决办法
1.配置类上实现SchedulingConfigurer接口,重写configureTasks方法即可

public class SchedulingConfig implements SchedulingConfigurer {
    private static final MyLog LOG = MyLog.getLog(MenuServiceImpl.class);

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }

2.定时任务与异步任务结合

配置类如下:

@Configuration
@EnableScheduling
public class SchedulingConfig {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Scheduled(cron = "0 0/10 * * * ?") // 每10分钟执行一次
    public void getToken() {
        logger.info("getToken定时任务启动");
    }

说明

类上带有@Configuration的类,等同于spring的XML配置文件,好处是使用Java代码可以检查类型安全。通常还会搭配其他注解来实现不同的需求,如本例中,搭配的@EnableScheduling。

在spring-boot中需要在类上添加@EnableScheduling注解来开启对计划任务的支持。

在开启对计划任务的支持后,需要@Scheduled注解的配合。@Scheduled是方法上注解,添加该注解的方法即为单个计划任务。@Scheduled注解定义了计划任务的执行计划,有两种方式可以定义:
1.@Scheduled(fixedRate = 5000) //通过@Scheduled声明该方法是计划任务,使用fixedRate属性每隔固定时间5秒执行一次
2.@Scheduled(cron = “0 0/10 * * * ?”) //使用cron属性可按照指定时间执行,本例指的是每10分钟执行一次;(cron使用详情参见

第二种

整合Quartz(spring boot2.0以下)

pom:

<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.0</version> 
</dependency>

任务类:

@Component
public class QuartzTask1 {
    private static final MyLog LOG = MyLog.getLog(MenuServiceImpl.class);

    public void execute() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOG.info("===============================");
    }

定时任务配置类:

@Configuration
public class QuartzConfigration { 
  /** 
   * attention: 
   * Details:配置定时任务 
   */
  @Bean(name = "jobDetail") 
  public MethodInvokingJobDetailFactoryBean detailFactoryBean(QuartzTask1 task) {// ScheduleTask为需要执行的任务 
    MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); 
    /* 
     * 是否并发执行 
     * 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, 
     * 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 
     */ 
    jobDetail.setConcurrent(false); 
      
    jobDetail.setName("srd-chhliu");// 设置任务的名字 
    jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 
      
    /* 
     * 为需要执行的实体类对应的对象 
     */ 
    jobDetail.setTargetObject(task); 
      
    /* 
     * execute 
     * 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的execute方法 
     */ 
    jobDetail.setTargetMethod("execute"); 
    return jobDetail; 
  } 
    
  /** 
   * attention: 
   * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务 
   */ 
  @Bean(name = "jobTrigger") 
  public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { 
    CronTriggerFactoryBean tigger = new CronTriggerFactoryBean(); 
    tigger.setJobDetail(jobDetail.getObject()); 
    tigger.setCronExpression("0 30 20 * * ?");// 初始时的cron表达式 
    tigger.setName("srd-chhliu");// trigger的name 
    return tigger; 
  
  } 
  
  /** 
   * attention: 
   * Details:定义quartz调度工厂 
   */
  @Bean(name = "scheduler") 
  public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) { 
    SchedulerFactoryBean bean = new SchedulerFactoryBean(); 
    // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job 
    bean.setOverwriteExistingJobs(true); 
    // 延时启动,应用启动1秒后 
    bean.setStartupDelay(1); 
    // 注册触发器 
    bean.setTriggers(cronJobTrigger); 
    return bean; 
  } 
}