揭开 spring-context 包中 ThreadPoolTaskScheduler 的面纱

本文深入探讨了SpringBoot项目中启用@EnableScheduling时,如何通过ThreadPoolTaskScheduler自动配置任务调度执行器。文章详细解析了ThreadPoolTaskScheduler的初始化过程,包括ScheduledExecutorService的创建,以及在XML配置中如何指定线程池大小。通过对源码的分析,揭示了ScheduledThreadPoolExecutor如何作为实际执行定时任务的组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于上一篇文章中提到的 SpringBoot 项目中当标注 @EnableScheduling 注解时会自动配置一个 ThreadPoolTaskScheduler 任务调度执行器 bean,并且 @Scheduled 的定时任务就是由该 bean 负责执行的,之前没有看过该类中的源码 , 今天正好在做定时任务好奇心的驱使下研究了一下源码:

源码路径:org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler

首先一起看一下这个类的继承关系图:
在这里插入图片描述
类关系中主要大部分是一些接口定义了一些规范,以及做一些初始化以及停止时的一些销毁工作 (不是真正执行定时任务的主角)。

任务执行主角:
在这里插入图片描述
类内部属性中有一个ScheduledExecutorService ,ScheduledExecutorService 是一个接口,也是定义些规范。 这个接口的实现类才是主要执行任务的
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

bean 的初始化流程(创建 ScheduledExecutorService 实现类对象):
1、ExecutorConfigurationSupport.afterPropertiesSet()
2、ExecutorConfigurationSupport.initialize()
3、ThreadPoolTaskScheduler.initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler)
4、ThreadPoolTaskScheduler.createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler)

由于 ExecutorConfigurationSupport 类中的 initializeExecutor 方法是一个抽象方法,所以是在子类中实现,也就是最终初始化是调用 ThreadPoolTaskScheduler 中的initializeExecutor 方法创建一个 ScheduledExecutorService 的实现类ScheduledThreadPoolExecutor 对象作为定时任务真正执行对象


	/**
	 * Calls {@code initialize()} after the container applied all property values.
	 * @see #initialize()
	 */
	@Override
	public void afterPropertiesSet() {
		initialize();
	}

	/**
	 * Set up the ExecutorService.
	 */
	public void initialize() {
		if (logger.isInfoEnabled()) {
			logger.info("Initializing ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
		}
		if (!this.threadNamePrefixSet && this.beanName != null) {
			setThreadNamePrefix(this.beanName + "-");
		}
		this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
	}

	/**
	 * Create the target {@link java.util.concurrent.ExecutorService} instance.
	 * Called by {@code afterPropertiesSet}.
	 * @param threadFactory the ThreadFactory to use
	 * @param rejectedExecutionHandler the RejectedExecutionHandler to use
	 * @return a new ExecutorService instance
	 * @see #afterPropertiesSet()
	 */
	protected abstract ExecutorService initializeExecutor(
			ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);


@Override
protected ExecutorService initializeExecutor(
		ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {

	this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);

	if (this.removeOnCancelPolicy) {
		if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
			((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(true);
		}
		else {
			logger.debug("Could not apply remove-on-cancel policy - not a ScheduledThreadPoolExecutor");
		}
	}

	return this.scheduledExecutor;
}
protected ScheduledExecutorService createExecutor(
			int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {

		return new ScheduledThreadPoolExecutor(poolSize, threadFactory, rejectedExecutionHandler);
}

ScheduledThreadPoolExecutor 类关系图:
在这里插入图片描述

public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory,
                                       RejectedExecutionHandler handler) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory, handler);
    }

构造方法内仅调用了父类线程池类的构造方法进行初始化。

最后如果在 SSM 项目中想注入一个 ThreadPoolTaskScheduler 对象,在 xml 中配置
<task:scheduler id=“scheduler” pool-size=“10” /> 即可,pool-size 指定线程池的大小。

	<xsd:element name="scheduler">
		<xsd:annotation>
			<xsd:documentation><![CDATA[
	Defines a ThreadPoolTaskScheduler instance with configurable pool size. See Javadoc
	for the org.springframework.scheduling.annotation.EnableScheduling annotation for
	information on a code-based alternative to this XML element.
			]]></xsd:documentation>
		</xsd:annotation>
		<xsd:complexType>
			<xsd:attribute name="id" type="xsd:string" use="required">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	The bean name for the generated ThreadPoolTaskScheduler instance.
	It will also be used as the default thread name prefix.
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="pool-size" type="xsd:string" use="optional">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	The size of the ScheduledExecutorService's thread pool. The default is 1.
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
		</xsd:complexType>
	</xsd:element>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值