您的位置:

SpringBoot定时器详解

SpringBoot作为现在最流行的Java Web框架之一,提供了一个简单、快捷、灵活的方式来添加定时任务。本文将会从多个方面来对SpringBoot定时器作详细的介绍,包括以下几个方面:

一、创建定时任务

创建一个定时任务只需要一个简单的注解即可。首先在你的主类上添加注解@EnableScheduling启用Spring的计划任务,然后创建一个带有@Scheduled注解的方法即可。例如:

    
    @SpringBootApplication
    @EnableScheduling
    public class DemoApplication {
    
        @Scheduled(cron = "0 0 1 * * ?")
        public void task() {
            // handle task
        }
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    

上述代码创建了一个名为task()的任务,它将在每天1点执行。可以通过配置不同的cron表达式来定制不同的执行频率。

二、并行执行与同步执行

默认情况下,SpringBoot的任务是同步执行的,这意味着一个任务将会在上一个任务完成之后才会执行。如果想要并行执行任务需要在方法上添加@Async注解:

    
    @Scheduled(fixedDelay = 1000)
    @Async
    public void task() {
        // handle task
        System.out.println(Thread.currentThread().getName() + " 执行完成!");
    }
    

上述代码将定时任务进行并行化,任务将会异步执行,并且@Async注解要和@Configuration、@EnableAsync注解一起使用。

三、使用线程池

大型应用中应该使用线程池来执行任务,而不是每次都新建一个线程。使用线程池可以提高任务的处理速度,并且能够更好的管理资源。

下面是使用线程池的一个例子:

    
    @Configuration
    @EnableScheduling
    public class ScheduleConfig implements SchedulingConfigurer {
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
            threadPoolTaskScheduler.setPoolSize(10);
            threadPoolTaskScheduler.initialize();
            taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
        }
    
        @Scheduled(fixedDelay = 1000)
        public void task() {
            //handle task
        }
    }
    

通过实现SchedulingConfigurer接口,可以配置使用线程池进行任务定时处理。ThreadPoolTaskScheduler是Spring提供的一种基于线程池的TaskScheduler,它可以设置线程数量、队列容量等参数。

四、使用Spring自带的定时任务组件

Spring Boot除了提供了自带的@Scheduled注解,还提供了自带的定时任务组件——ScheduledExecutorService,它提供了更加复杂的定时任务控制。以下是使用自带的定时任务组件的一个例子:

    
    @Configuration
    @EnableAsync
    public class ScheduleConfig {
        
        private static final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(5);
    
        public static ScheduledExecutorService getExecutorService() {
            return executorService;
        }
    
        @Bean
        public TaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(4);
            executor.setMaxPoolSize(8);
            executor.setQueueCapacity(10000);
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
    }
    

上述代码创建了一个包含5个线程的ScheduledExecutorService线程池,并使用@Bean注解在SpringBoot中创建了一个TaskExecutor对象。需要注意到的是,为了支持异步调用,这里使用了@EnableAsync注解。

五、使用第三方定时任务组件

Spring Boot并不能解决所有的定时任务问题,有时候需要考虑使用第三方的定时任务组件来达到更好的定时任务控制。以下是使用Quartz定时任务组件的一个例子:

    
    @Configuration
    public class ScheduleConfig {
    
        @Bean(name = "jobDetail")
        public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {// ScheduleTask为需要执行的任务
            MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
            /* 是否并发执行 */
            jobDetail.setConcurrent(false);
            /* 设置任务的名字 */
            jobDetail.setName("srd-11111");
            /* 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 */
            jobDetail.setGroup("srd");
            /*
             * 为需要执行的实体类对应的对象
             */
            jobDetail.setTargetObject(task);
            /*
             * srd()方法为需要执行的方法 这个方法是要反复执行的
             */
            jobDetail.setTargetMethod("srd");
            return jobDetail;
        }
    
        @Bean(name = "jobTrigger")
        public SimpleTriggerFactoryBean simpleTriggerFactoryBean(@Qualifier("jobDetail") MethodInvokingJobDetailFactoryBean jobDetail) {
            SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
            factoryBean.setJobDetail(jobDetail.getObject());
            /* 设置触发时间 */
            factoryBean.setStartDelay(0);// 设置执行周期
            factoryBean.setRepeatInterval(10000);
            factoryBean.setRepeatCount(100);
            return factoryBean;
        }
    
        @Bean(name = "scheduler")
        public SchedulerFactoryBean schedulerFactory(@Qualifier("jobTrigger") Trigger cronJobTrigger) {
            SchedulerFactoryBean bean = new SchedulerFactoryBean();
            /* 用于quartz集群,QuartzScheduler 启动时更新己存在的Job */
            bean.setOverwriteExistingJobs(true);
            /* 延时启动,应用启动1秒后 */
            bean.setStartupDelay(1);
            /* 注册触发器 */
            bean.setTriggers(cronJobTrigger);
            return bean;
        }
    }
    

上述代码创建了一个Quartz定时任务组件,并且使用@Bean注解注册了需要执行的任务、任务的触发器和任务组件本身。

总结

本文从创建定时任务、并行执行与同步执行、使用线程池、使用Spring自带的定时任务组件和使用第三方定时任务组件这几个方面详细的介绍了SpringBoot定时器的使用方法,希望这篇文章对你有所帮助。