场景应用:如何在SpringBoot框架下实现一个定时任务?

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了场景应用:如何在SpringBoot框架下实现一个定时任务?相关的知识,希望对你有一定的参考价值。

文章目录

如何在SpringBoot框架下实现一个定时任务?

原生API:Timer

java原生提供的api去实现一个定时任务

代码如下:

package com.yyl;

import java.util.Timer;
import java.util.TimerTask;

public class javaJob 
    public static void main(String[] args) 
        // 利用java的api Timer来完成一个定时任务
        Timer timer = new Timer();
        // 其实这个技术也是基于java的线程去做的
        TimerTask task=new TimerTask() 
            @Override
            public void run() 
                System.out.println("这是一个定时任务");
            
        ;
        timer.schedule(task,0,2000);
    


运行定时任务的结果:

线程池:ThreadPoolTaskScheduler

Spring给我们提供了可执行定时任务的线程池ThreadPoolTaskScheduler,该线程池提供了多个可以与执行定时任务的方法,如下图。在Spring Boot中,只需要在配置类中启用线程池注解,就可以直接使用这个线程池了。

ThreadPoolTaskScheduler常用方法如下:

案例:SpringBoot使用线程池

线程池配置类:

package com.yyl.Study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync    // 启用 Spring 的异步方法执行功能
@Configuration
public class ExecutorConfig 


    // new ThreadPoolTaskExecutor();
    /**
     * 核心线程数量,默认1
     */
    private int corePoolSize = 3;

    /**
     * 最大线程数量,默认Integer.MAX_VALUE;
     */
    private int maxPoolSize = 5;

    /**
     * 空闲线程存活时间
     */
    private int keepAliveSeconds = 60;

    /**
     * 线程阻塞队列容量,默认Integer.MAX_VALUE
     */
    private int queueCapacity = 1;

    /**
     * 是否允许核心线程超时
     */
    private boolean allowCoreThreadTimeOut = false;




    @Bean("asyncExecutor")
    public Executor asyncExecutor() 
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 配置核心线程数量
        executor.setCorePoolSize(corePoolSize);
        // 配置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 配置队列容量
        executor.setQueueCapacity(queueCapacity);
        // 配置空闲线程存活时间
        executor.setKeepAliveSeconds(keepAliveSeconds);

        executor.setAllowCoreThreadTimeOut(allowCoreThreadTimeOut);

        // 设置拒绝策略,直接在execute方法的调用线程中运行被拒绝的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        // 执行初始化
        executor.initialize();
        return executor;
    

创建Service接口,执行异步任务

package com.yyl.Study.timedtask;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Random;

@Service
public class AsyncService 

    @Async("asyncExecutor")
    public void executeAsync()
        int id = new Random().nextInt(100);
        try 
            Thread.sleep(1000);
         catch (InterruptedException e) 
            e.printStackTrace();
        
    


编写测试代码:

package com.yyl.Study;

import com.yyl.Study.timedtask.AsyncService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class TimedTask 

    @Autowired
    AsyncService asyncService;

    @Test
    public void asyncTask()
        asyncService.executeAsync();
    


定时任务框架:Quarze

但是现在在我们企业级应用中定时任务的应用非常广泛,于是就出现了完成定时任务的技术比如Quarze,这个技术在现在市面上非常流行

你要想在springboot中整合这个技术,我们首先来了解几个词

名字解释
工作(job)用于执行具体的任务
工作明细(jobDetail)用于定义定时工作的信息
触发器(Trigger)用于描述触发工作的规则,和定义调度通常用Cron来进行定义调度的规则
调度(scheduler)用于描述工作明细和触发器之间的关系

理解以上的四个词的含义我们来进行整合Quarze案例:

第一步就是来导入整合Quarze的坐标

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

这里我们不需要做Quarze的配置,我们要做的是去继承一个quarze的一个抽象类QuartzJobBean,代表这个是一个Job然后是实现这个抽象类中的方法就是我们具体的工作

package com.yyl.Study.timedtask;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class Myquartz extends QuartzJobBean 
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException 
        System.out.println("我是quartz!");
    


这里我们就完成我们上面所讲的一个工作的创建。

创建完一个job后我们是不是要创建一个jobDetail工作明细来绑定我们的工作,再创建一个触发器来绑定工作明细,再由时间调度说明jobDetail和Tigger的关系

package com.yyl.Study.config;

import com.yyl.Study.timedtask.Myquartz;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//这个类主要是做配置类去配置JobDetail,Trigger即配置工作明细,和触发器,
@Configuration
public class QuartzConfig 
    @Bean
    public JobDetail jobDetail() 
        //在这里工作明细要绑定一个job
        //现在这个工作就完成了这里必须要加上storeDurably,这个作用是当这个任务没有被执行也会一直存在保持持久化
        return JobBuilder.newJob(Myquartz.class).storeDurably().build();
    

    @Bean
    public Trigger trigger() 

        //这里触发器要绑定一个工作明细JobDetail 同时要完成调度
        //这里要说明一下withSchedule是完成调度的下面这行代码是实现时间调度的要
        //要说明一下0 0 0 0 0 0,分别代表 秒 分 时 日 月 星期 其中日 和星期会有冲突通常我们都只配一个 另一个用?代替
        //ScheduleBuilder<? extends Trigger> schdule=CronScheduleBuilder.cronSchedule("0 0 0 0 0 0") ;
        //如CronScheduleBuilder.cronSchedule("0 0 0 1 2 ?")这就代表了2月的第一天0秒0分0时 我们还可以配*代表任意 ;
        //还可以如CronScheduleBuilder.cronSchedule("0/15 * * * * ?")代表没个15秒执行一次
        ScheduleBuilder schdule = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        //forJob就时绑定工作明细
        return TriggerBuilder.newTrigger().forJob(jobDetail()).withSchedule(schdule).build();
    

这是不是属于一个配置啊。那么我们此时不再配置中配置这些信息了,我们创建一个配置类来让这些bean加载到spring容器中。

这段代码完成后我们就把这些事请都做完了。在这里我要提醒一下特别要注意

ScheduleBuilder schdule=CronScheduleBuilder.cronSchedule("0/5 * * * * ?") ;

如何对调度进行配置我上面的代码是每个间隔十五秒执行一次在任意时刻。具体的可以再去学学,我不学了先!!!!!

以上是关于场景应用:如何在SpringBoot框架下实现一个定时任务?的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot微服务框架概述

谈谈spring是如何实现的?

Spring Boot框架下实现Excel服务端导入导出

redis--springboot实现redis的分布式锁

Spring Boot框架下实现Excel服务端导入导出

Spring Boot框架下实现Excel服务端导入导出