Pārlūkot izejas kodu

feature 解决子线程无法获取上下文信息导致无法切库的问题

xiahan 4 mēneši atpakaļ
vecāks
revīzija
b61b014812

+ 43 - 10
zhsw-common/src/main/java/com/rongwei/zhsw/system/config/ThreadPoolConfig.java

@@ -4,6 +4,11 @@ import cn.hutool.core.thread.ExecutorBuilder;
 import cn.hutool.core.thread.ThreadFactoryBuilder;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.TaskDecorator;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
 
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -16,19 +21,47 @@ import java.util.concurrent.TimeUnit;
  */
 
 @Configuration
-public class ThreadPoolConfig {
+public class ThreadPoolConfig implements AsyncConfigurer {
     public static final String NAME_PRE="zhsw-";
 
     @Bean("customThreadPool")
-    public static ThreadPoolExecutor getExecutor(){
-        return  ExecutorBuilder.create()
-                .setCorePoolSize(8)
-                .setMaxPoolSize(16)
-                .setKeepAliveTime(60, TimeUnit.SECONDS)
-                .setHandler(new ThreadPoolExecutor.CallerRunsPolicy())
-                .setAllowCoreThreadTimeOut(true)
-                .setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(NAME_PRE).build())
-                .build();
+    @Override
+    public ThreadPoolTaskExecutor getAsyncExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(8);
+        executor.setMaxPoolSize(16);
+        executor.setQueueCapacity(30);
+        executor.setTaskDecorator(new RequestContextTaskDecorator());
+        executor.initialize();
+        return executor;
     }
+    static class RequestContextTaskDecorator implements TaskDecorator {
+        @Override
+        public Runnable decorate(Runnable runnable) {
+            // 获取主线程的请求上下文
+            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+            return () -> {
+                try {
+                    // 将主线程的请求上下文绑定到子线程
+                    RequestContextHolder.setRequestAttributes(requestAttributes, true); // true 表示继承模式
+                    runnable.run();
+                } finally {
+                    // 清理子线程的上下文,避免内存泄漏
+                    RequestContextHolder.resetRequestAttributes();
+                }
+            };
+        }
+    }
+    // public static ThreadPoolExecutor getExecutor(){
+    //     ThreadPoolExecutor threadPoolExecutor = ExecutorBuilder.create()
+    //             .setCorePoolSize(8)
+    //             .setMaxPoolSize(16)
+    //             .setKeepAliveTime(60, TimeUnit.SECONDS)
+    //             .setHandler(new ThreadPoolExecutor.CallerRunsPolicy())
+    //             .setAllowCoreThreadTimeOut(true)
+    //             .setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(NAME_PRE).build())
+    //             .build();
+    //     return threadPoolExecutor;
+    // }
 
 }