@Configuration
public class TzCommonThreadPoolConfig {
/**
* 线程池配置:核心线程数
*/
@Value("${sys.pool.corePoolSize:8}")
private int corePoolSize;
/**
* 线程池配置:最大线程数
*/
@Value("${sys.pool.maxPoolSize:16}")
private int maxPoolSize;
/**
* 线程池配置:队列容量
*/
@Value("${sys.pool.commonQueueCapacity:2048}")
private int queueCapacity;
/**
* 线程池配置:线程活跃时间(秒)
*/
@Value("${sys.pool.commonKeepAliveSeconds:60}")
private int keepAliveSeconds;
/**
* 通用公共线程池
* <p>
* 可传递当前用户信息
* 非强业务性配置,默认使用通用配置量,队列容量和活跃时间自定义
* 频率较高及业务性较强的建议自定义线程池处理
*
* @return Executor
*/
@Bean(name = "commonThreadPool")
public Executor commonThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(corePoolSize);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 设置队列容量
executor.setQueueCapacity(queueCapacity);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(keepAliveSeconds);
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 设置默认线程名称
executor.setThreadNamePrefix("commonThreadPool-%d");
// 增加 TaskDecorator 属性的配置
executor.setTaskDecorator(new UserTaskDecorator());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
// 初始化线程池
executor.initialize();
return executor;
}
}
/**
* 用户信息传递装饰器
*/
public class UserTaskDecorator implements TaskDecorator {
/**
* Decorate the given {@code Runnable}, returning a potentially wrapped
* {@code Runnable} for actual execution, internally delegating to the
* original {@link Runnable#run()} implementation.
*
* @param runnable the original {@code Runnable}
* @return the decorated {@code Runnable}
*/
@Override
public Runnable decorate(@NotNull Runnable runnable) {
TzmallUser user = UserInfoContext.getUser();
return () -> UserInfoContext.resetUserInfo(user, runnable::run);
}
}
public class UserInfoContext {
/**
* 用户信息ThreadLocal
*/
private static ThreadLocal<TzmallUser> userInfo = new ThreadLocal<>();
/**
* 获取Authentication
*/
public static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
/**
* 默认用户
*/
private final static TzmallUser defaultUser;
static {
defaultUser = new TzmallUser(TzmallUser.SYSTEM, StrUtil.EMPTY, Collections.emptySet());
defaultUser.setId(xxL);
defaultUser.setName("系统");
defaultUser.setFirmId(xxL);
defaultUser.setFirmName("平台");
defaultUser.setUserType(xx);
defaultUser.setPhone("");
}
public UserInfoContext() {
}
/**
* 获取用户信息
*/
public static TzmallUser getUser(){
// 如果本地缓存存在,则返回本地缓存TzUser
if (ObjectUtil.isNotNull(userInfo.get())) {
return userInfo.get();
}
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
return getUser(authentication);
}
/**
* 获取用户信息
*
* @param authentication authentication
* @return TzmallUser
*/
public static TzmallUser getUser(Authentication authentication) {
Object principal = authentication.getPrincipal();
if (principal instanceof TzmallUser) {
return (TzmallUser) principal;
}
return null;
}
/**
* 获取登录用户(如果当前未登录抛出异常!)
*
* @return TzmallUser
*/
public static TzmallUser getLoginUser() {
TzmallUser tzUser = getUser();
if (tzUser == null) {
throw new ServiceException(CodeMsg.LOGIN_INVALID);
}
return tzUser;
}
/**
* 获取用户信息,如不存在取默认用户对象
*
*/
public static TzmallUser getUserOrDefault(){
TzmallUser user = getUser();
if (user == null) {
return defaultUser;
}
return user;
}
/**
* 重置登录信息,并执行代码
*
*/
public static <T> T resetUserInfo(TzmallUser tzUser, Supplier<T> supplier) {
TzmallUser originalUser = userInfo.get();
try {
userInfo.set(tzUser);
return supplier.get();
} finally {
if (originalUser == null) {
userInfo.remove();
} else {
userInfo.set(originalUser);
}
}
}
/**
* 重置登录信息,并执行代码
*
*/
public static void resetUserInfo(TzmallUser tzUser, LambdaExecutor lambdaExecutor) {
TzmallUser originalUser = userInfo.get();
try {
userInfo.set(tzUser);
lambdaExecutor.executor();
} finally {
if (originalUser == null) {
userInfo.remove();
} else {
userInfo.set(originalUser);
}
}
}
}
配置类放在common,引用该common的模块相当于建立了自己的线程池
#启动类添加
@EnableAsync
#使用
@Async("commonThreadPool")
文章介绍了如何在SpringBoot应用中配置一个通用的线程池,包括核心线程数、最大线程数、队列容量和线程活跃时间。同时,还展示了如何通过UserTaskDecorator传递用户信息到线程中。
1242

被折叠的 条评论
为什么被折叠?



