在Spring boot项目中实现定时任务

 一. 在Spring boot 项目中实现简单的定时任务: 

        在Spring boot项目中实现定时任务通常用Spring的@Scheduled注解来完成。

        示例:

        1.首先,在Spring boot 项目中创建一个定时任务类,例如:TaskScheduler:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class TaskScheduler {

    // 每隔5秒执行一次任务
    @Scheduled(fixedRate = 5000)
    public void scheduledTask() {
        System.out.println("定时任务执行啦!");
    }
}

        2.在启动类或者配置类上添加@EnableScheduling注解,以开启定时任务的支持:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

        3.完成以上步骤后,当运行Spring Boot时,定时任务会按照@Scheduled注解中配置的时间间隔执行。

二. @Scheduled注解:

        @Scheduled注解是Spring框架中用于配置定时任务的注解之一。通过在方法上添加@Scheduled注解,可以指定方法在特定时间执行,或者以固定时间间隔执行。在使用@Scheduled时,可以指定多种参数,包括fixedDelay(固定延迟时间执行),fixedRate(固定频率执行),cron表达式(按照cron表达式规则执行)等,以满足不同的定时任务需求。

        @Scheduled各个参数用法:

  1. fixedDelay:

    • 用法:@Scheduled(fixedDelay = 1000)
    • 解释:指定方法执行结束后延迟多久再次执行,单位为毫秒。
    • 示例:@Scheduled(fixedDelay = 5000) 表示每次任务执行结束后延迟 5 秒再次执行。
  2. fixedRate:

    • 用法:@Scheduled(fixedRate = 2000)
    • 解释:指定方法开始执行后多久再次执行,单位为毫秒。不关心方法执行时间长短,固定频率执行。
    • 示例:@Scheduled(fixedRate = 3000) 表示每隔 3 秒执行一次任务,不论任务执行时间长短。
  3. initialDelay:

    • 用法:@Scheduled(initialDelay = 5000, fixedRate = 2000)
    • 解释:指定首次执行任务的延迟时间,单位为毫秒。
    • 示例:@Scheduled(initialDelay = 10000, fixedRate = 3000) 表示首次执行任务将在 10 秒后,之后每隔 3 秒执行一次。
  4. cron:

    • 用法:@Scheduled(cron = "0 0 12 * * ?")
    • 解释:使用 cron 表达式来指定任务执行的时间规则。
    • 示例:@Scheduled(cron = "0 0/5 8-20 * * ?") 表示在每天的上午 8 点到晚上 8 点,每隔 5 分钟执行一次任务。

cron表达式的各个字段及其含义:

  • 秒(Seconds):取值范围为0-59。
  • 分钟(Minutes):取值范围为0-59。
  • 小时(Hours):取值范围为0-23。
  • 日期(Day of month):取值范围为1-31。
  • 月份(Month):取值范围为1-12或使用英文缩写(如JAN-DEC)。
  • 星期(Day of week):取值范围为0-7或使用英文缩写(SUN-SAT),其中0和7都表示星期日。

cron表达式的格式如下:

"秒 分 时 日 月 周"

例如,如果要每天中午12点执行一次任务,可以使用如下的cron表达式:

@Scheduled(cron = "0 0 12 * * ?")

在上述表达式中,0 0 12 * * ?表示每天中午12点执行一次任务。在实际使用中,根据具体的需求可以灵活设置cron表达式来指定定时任务的执行时间。需要注意的是,cron表达式中不同字段之间用空格分隔,同时还可以使用通配符、区间等方式来设置更复杂的定时规则。

        在cron表达式中,可以使用一些特殊的符号来设置更复杂的定时规则。以下是常用的通配符和区间符号: 

  1. 通配符

    • *:表示匹配任意值。例如,*在分钟字段表示每分钟都执行。
    • ?:仅用于日和星期字段,表示不指定具体值。
  2. 区间

    • -:表示范围。例如,1-5在小时字段表示1点到5点之间每个整点触发。
    • /:表示步长。例如,0/5在秒字段表示每隔5秒执行一次。
  3. 列表

    • ,:表示列表。可以指定多个值逗号分隔。例如,1,3,5在小时字段表示1点、3点和5点各执行一次。
  4. 通配符和区间的结合

    • 可以结合通配符和区间来设置更复杂的定时规则。例如,0 0 0 1-10 * ?表示在每个月的1号到10号的午夜零点触发。
  5. 工作日和非工作日

    • W:表示最接近给定日期的工作日(周一至周五)。例如,15W在日字段表示离每月15号最近的工作日触发。
    • L:表示最后一天。例如,L在日字段表示每个月的最后一天触发。

三. 实现定时任务的异步执行: 

        为什么要实现异步执行定时任务?主要有以下优点:   

  1. 提高系统性能

    • 异步执行可以避免因为同步执行而造成的阻塞,提高系统的并发能力和响应速度。通过异步执行,系统可以同时处理多个任务,充分利用系统资源,提升系统整体性能。
  2. 增强用户体验

    • 异步执行可以确保用户操作的及时响应,避免因为任务耗时长而导致用户界面假死或响应缓慢的情况发生。用户在等待任务完成的过程中可以继续进行其他操作,提升用户体验。
  3. 任务解耦和模块化

    • 通过异步执行,可以将任务之间的耦合度降低,实现任务的解耦和模块化。不同的任务可以独立执行,各自管理自己的状态和资源,提高系统的灵活性和可维护性。
  4. 提高系统稳定性

    • 异步执行可以将任务的执行隔离开来,降低任务之间的相互影响,提高系统的稳定性和容错能力。即使某个任务执行失败,也不会对系统的整体运行造成严重影响。
  5. 资源管理和调度优化

    • 通过异步执行,可以更好地管理系统资源,优化任务调度策略,提高系统的资源利用率和效率。合理安排任务的执行顺序和时间,可以更好地满足业务需求。

        实现定时任务异步执行的方法有多种,这里主要介绍使用Spring Framework中的@Async注解来实现异步执行定时任务,通过在方法上添加@Async注解,Spring会在调用该方法时自动创建一个新的线程来执行该方法,从而实现异步执行。 

        代码示例:

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

@Service
public class MyService {

    @Async
    public void doSomethingAsync() {
        // 异步执行的任务代码
    }
}

        在使用@Async注解时,需要在Spring配置类或者启动类上添加@EnableAsync注解来启用对异步方法的支持,例如:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

@Configuration
@EnableAsync
public class AppConfig {
    // 配置信息
}

        当使用@Async注解时,Spring会默认使用一个线程池来执行异步方法。这个线程池是由Spring自动配置的,默认情况下,它会使用一个SimpleAsyncTaskExecutor来执行异步方法。

        我们可以在Spring的配置类中创建一个TaskExecutor bean,并在使用@Async注解时指定要使用的线程池。下面是一个简单的示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
public class AppConfig implements AsyncConfigurer {

    @Override
    @Bean
    public TaskExecutor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }
}

        在上面的示例中,我们创建了一个ThreadPoolTaskExecutor bean,并通过重写AsyncConfigurer接口的getAsyncExecutor()方法,返回我们自定义的线程池实例。在这个示例中,我们设置了线程池的核心线程数、最大线程数和队列容量,并将其初始化后返回给Spring容器。

        接着,我们可以在需要使用异步方法的地方,使用@Async注解并指定要使用的线程池。例如:

import org.springframework.scheduling.annotation.Async;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Async("getAsyncExecutor")
    public void doSomethingAsync() {
        // 异步执行的任务代码
    }
}

        在上面的示例中,我们在doSomethingAsync方法上使用了@Async("getAsyncExecutor")注解,指定了要使用的线程池名为getAsyncExecutor,这样就可以使用我们自定义的线程池来执行异步方法了。

        那么要实现定时任务的异步执行就很简单了,例如:

    @Async("threadPoolTaskExecutor")
    @Scheduled(cron = "0 0/30 * * * ?")
    public void GrabFileInformation() {
        dataService.getAllDataTASK();
        log.info("执行了抓取数据定时任务!");
    }

        记得在配置类上加上@EnableAsync和@EnableScheduing注解即可。

  • 48
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值