refactor(core): 重构线程池自动配置代码

This commit is contained in:
2025-09-13 21:34:14 +08:00
parent 7ead337165
commit 68895787a7
5 changed files with 176 additions and 141 deletions

View File

@@ -1,86 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.core.autoconfigure.threadpool;
import cn.hutool.core.util.ArrayUtil;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.exception.BaseException;
import java.util.Arrays;
import java.util.concurrent.Executor;
/**
* 异步任务自动配置
*
* @author Charles7c
* @since 1.0.0
*/
@Lazy
@AutoConfiguration
@EnableAsync(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.task.execution.extension", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
public class AsyncAutoConfiguration implements AsyncConfigurer {
private static final Logger log = LoggerFactory.getLogger(AsyncAutoConfiguration.class);
private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
public AsyncAutoConfiguration(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
this.threadPoolTaskExecutor = threadPoolTaskExecutor;
}
/**
* 异步任务线程池配置
*/
@Override
public Executor getAsyncExecutor() {
return threadPoolTaskExecutor;
}
/**
* 异步任务执行时的异常处理
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append("Exception message: ")
.append(throwable.getMessage())
.append(", Method name: ")
.append(method.getName());
if (ArrayUtil.isNotEmpty(objects)) {
sb.append(", Parameter value: ").append(Arrays.toString(objects));
}
throw new BaseException(sb.toString());
};
}
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'AsyncConfigurer' completed initialization.");
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.core.autoconfigure.threadpool;
import cn.hutool.core.util.ArrayUtil;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.task.ThreadPoolTaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.core.exception.BaseException;
import java.util.Arrays;
import java.util.concurrent.Executor;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link TaskExecutor}.
*
* @author Charles7c
* @since 1.0.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.task.execution.extension", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
class TaskExecutionConfiguration {
private static final Logger log = LoggerFactory.getLogger(TaskExecutionConfiguration.class);
@Value("${spring.task.execution.pool.core-size:#{T(java.lang.Runtime).getRuntime().availableProcessors() + 1}}")
private int corePoolSize;
@Value("${spring.task.execution.pool.max-size:#{T(java.lang.Runtime).getRuntime().availableProcessors() * 2}}")
private int maxPoolSize;
@Bean
public ThreadPoolTaskExecutorCustomizer threadPoolTaskExecutorCustomizer(ThreadPoolExtensionProperties properties) {
return executor -> {
// 核心(最小)线程数
executor.setCorePoolSize(corePoolSize);
// 最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 当线程池的任务缓存队列已满并且线程池中的线程数已达到 maxPoolSize 时采取的任务拒绝策略
executor.setRejectedExecutionHandler(properties.getExecution()
.getRejectedPolicy()
.getRejectedExecutionHandler());
};
}
/**
* {@link Async} 异步任务线程池配置
*/
@EnableAsync(proxyTargetClass = true)
static class AsyncThreadPoolConfigurer implements AsyncConfigurer {
private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
public AsyncThreadPoolConfigurer(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
this.threadPoolTaskExecutor = threadPoolTaskExecutor;
}
@Override
public Executor getAsyncExecutor() {
return threadPoolTaskExecutor;
}
/**
* 异步任务执行时的异常处理
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append("Exception message: ")
.append(throwable.getMessage())
.append(", Method name: ")
.append(method.getName());
if (ArrayUtil.isNotEmpty(objects)) {
sb.append(", Parameter value: ").append(Arrays.toString(objects));
}
throw new BaseException(sb.toString());
};
}
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'TaskExecutor-@Async' completed initialization.");
}
}
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'TaskExecutor' completed initialization.");
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.continew.starter.core.autoconfigure.threadpool;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.task.ThreadPoolTaskSchedulerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link TaskScheduler}.
*
* @author Charles7c
* @since 1.0.0
*/
@Configuration(proxyBeanMethods = false)
@EnableScheduling
@ConditionalOnProperty(prefix = "spring.task.scheduling.extension", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
class TaskSchedulingConfiguration {
private static final Logger log = LoggerFactory.getLogger(TaskSchedulingConfiguration.class);
@Bean
public ThreadPoolTaskSchedulerCustomizer threadPoolTaskSchedulerCustomizer(ThreadPoolExtensionProperties properties) {
return executor -> executor.setRejectedExecutionHandler(properties.getScheduling()
.getRejectedPolicy()
.getRejectedExecutionHandler());
}
@PostConstruct
public void postConstruct() {
log.debug("[ContiNew Starter] - Auto Configuration 'TaskScheduler' completed initialization.");
}
}

View File

@@ -16,18 +16,10 @@
package top.continew.starter.core.autoconfigure.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.task.ThreadPoolTaskExecutorCustomizer;
import org.springframework.boot.task.ThreadPoolTaskSchedulerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import top.continew.starter.core.constant.PropertiesConstants;
/**
* 线程池自动配置
@@ -38,49 +30,6 @@ import top.continew.starter.core.constant.PropertiesConstants;
@Lazy
@AutoConfiguration
@EnableConfigurationProperties(ThreadPoolExtensionProperties.class)
@Import({TaskExecutionConfiguration.class, TaskSchedulingConfiguration.class})
public class ThreadPoolAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(ThreadPoolAutoConfiguration.class);
@Value("${spring.task.execution.pool.core-size:#{T(java.lang.Runtime).getRuntime().availableProcessors() + 1}}")
private int corePoolSize;
@Value("${spring.task.execution.pool.max-size:#{T(java.lang.Runtime).getRuntime().availableProcessors() * 2}}")
private int maxPoolSize;
/**
* 异步任务线程池配置
*/
@Bean
@ConditionalOnProperty(prefix = "spring.task.execution.extension", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
public ThreadPoolTaskExecutorCustomizer threadPoolTaskExecutorCustomizer(ThreadPoolExtensionProperties properties) {
return executor -> {
// 核心(最小)线程数
executor.setCorePoolSize(corePoolSize);
// 最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 当线程池的任务缓存队列已满并且线程池中的线程数已达到 maxPoolSize 时采取的任务拒绝策略
executor.setRejectedExecutionHandler(properties.getExecution()
.getRejectedPolicy()
.getRejectedExecutionHandler());
log.debug("[ContiNew Starter] - Auto Configuration 'TaskExecutor' completed initialization.");
};
}
/**
* 定时任务线程池配置
*/
@EnableScheduling
@ConditionalOnProperty(prefix = "spring.task.scheduling.extension", name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true)
public static class TaskSchedulerConfiguration {
@Bean
public ThreadPoolTaskSchedulerCustomizer threadPoolTaskSchedulerCustomizer(ThreadPoolExtensionProperties properties) {
return executor -> {
executor.setRejectedExecutionHandler(properties.getScheduling()
.getRejectedPolicy()
.getRejectedExecutionHandler());
log.debug("[ContiNew Starter] - Auto Configuration 'TaskScheduler' completed initialization.");
};
}
}
}

View File

@@ -1,3 +1,2 @@
top.continew.starter.core.autoconfigure.application.ApplicationAutoConfiguration
top.continew.starter.core.autoconfigure.threadpool.ThreadPoolAutoConfiguration
top.continew.starter.core.autoconfigure.threadpool.AsyncAutoConfiguration
top.continew.starter.core.autoconfigure.threadpool.ThreadPoolAutoConfiguration