springboot定时任务线程池配置拾遗--利用配置类进行配置

springboot定时任务线程池配置拾遗--利用配置类进行配置

1 springboot自动装配

自从上次简单了解了spring中schedule的线程池配置之后,我又去粗略学习了一下相关的源码,梳理了一下springboot是如何装配线程池的。

1.1 通过TaskSchedulingProperties获取yaml参数

TaskSchedulingProperties是一个schedule的配置类,它通过@ConfigurationProperties("spring.task.scheduling")注解注入yaml配置文件中schedule相关的配置。如果我们没有做配置,它默认线程名称为“scheduling”,线程容量是1,不开启优雅关机。所以默认情况下定时任务是单线程异步的。来看一下源码:

@ConfigurationProperties("spring.task.scheduling")
public class TaskSchedulingProperties {
    private final TaskSchedulingProperties.Pool pool = new TaskSchedulingProperties.Pool();
    private final TaskSchedulingProperties.Shutdown shutdown = new TaskSchedulingProperties.Shutdown();
    private String threadNamePrefix = "scheduling-";

    public TaskSchedulingProperties() {
    }

    public TaskSchedulingProperties.Pool getPool() {
        return this.pool;
    }

    public TaskSchedulingProperties.Shutdown getShutdown() {
        return this.shutdown;
    }

    public String getThreadNamePrefix() {
        return this.threadNamePrefix;
    }

    public void setThreadNamePrefix(String threadNamePrefix) {
        this.threadNamePrefix = threadNamePrefix;
    }

    public static class Shutdown {
        private boolean awaitTermination;
        private Duration awaitTerminationPeriod;

        public Shutdown() {
        }

        public boolean isAwaitTermination() {
            return this.awaitTermination;
        }

        public void setAwaitTermination(boolean awaitTermination) {
            this.awaitTermination = awaitTermination;
        }

        public Duration getAwaitTerminationPeriod() {
            return this.awaitTerminationPeriod;
        }

        public void setAwaitTerminationPeriod(Duration awaitTerminationPeriod) {
            this.awaitTerminationPeriod = awaitTerminationPeriod;
        }
    }

    public static class Pool {
        private int size = 1;

        public Pool() {
        }

        public int getSize() {
            return this.size;
        }

        public void setSize(int size) {
            this.size = size;
        }
    }
}

1.2 TaskSchedulingAutoConfiguration自动配置类根据TaskSchedulingProperties的配置装配线程池

TaskSchedulingAutoConfiguration是一个springboot的自动配置类,会读取TaskSchedulingProperties中的配置参数。当存在定时任务相关BBP的同时不存在定时任务管理器相关的Bean时,它就会根据参数自动配置一个定时任务线程池。看一下源码:

@ConditionalOnClass({ThreadPoolTaskScheduler.class})
@AutoConfiguration(
    after = {TaskExecutionAutoConfiguration.class}
)
@EnableConfigurationProperties({TaskSchedulingProperties.class})
public class TaskSchedulingAutoConfiguration {
    public TaskSchedulingAutoConfiguration() {
    }

    @Bean
    @ConditionalOnBean(
        name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
    )
    @ConditionalOnMissingBean({SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class})
    public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
        return builder.build();
    }

    @Bean
    @ConditionalOnBean(
        name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
    )
    public static LazyInitializationExcludeFilter scheduledBeanLazyInitializationExcludeFilter() {
        return new ScheduledBeanLazyInitializationExcludeFilter();
    }

    @Bean
    @ConditionalOnMissingBean
    public TaskSchedulerBuilder taskSchedulerBuilder(TaskSchedulingProperties properties, ObjectProvider<TaskSchedulerCustomizer> taskSchedulerCustomizers) {
        TaskSchedulerBuilder builder = new TaskSchedulerBuilder();
        builder = builder.poolSize(properties.getPool().getSize());
        Shutdown shutdown = properties.getShutdown();
        builder = builder.awaitTermination(shutdown.isAwaitTermination());
        builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());
        builder = builder.threadNamePrefix(properties.getThreadNamePrefix());
        builder = builder.customizers(taskSchedulerCustomizers);
        return builder;
    }
}

2 配置类线程池配置方式

从源码里可以看到,自动装配线程池的一个条件是不存在{SchedulingConfigurer.class, TaskScheduler.class, ScheduledExecutorService.class}的Bean。所以我们应该也可以主动配置一个线程池Bean,并且这种情况下将会覆盖yaml配置的参数。下面我就创建一个定时任务线程池的配置类进行测试:

@Configuration
public class ScheduleConfig {

    @Bean
    public ThreadPoolTaskScheduler configScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(2);
        scheduler.setThreadNamePrefix("nagiumi-config-scheduler-");
        return scheduler;
    }
}

再次启动项目,输出内容如下:

nagiumi-config-scheduler-1------run1···Thu Nov 23 20:53:42 CST 2023
nagiumi-config-scheduler-1------run1···Thu Nov 23 20:53:43 CST 2023
nagiumi-config-scheduler-1------run1···Thu Nov 23 20:53:44 CST 2023
nagiumi-config-scheduler-1------run1···Thu Nov 23 20:53:45 CST 2023
nagiumi-config-scheduler-2------run2···Thu Nov 23 20:53:45 CST 2023
nagiumi-config-scheduler-1------run1···Thu Nov 23 20:53:46 CST 2023

可以看到定时任务可以实现多线程同步进行,并且确实覆盖了yaml配置的参数。

posted @   pjgyr  阅读(418)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示