一個項目中既須要異步任務, 也須要調度任務, 想把這兩個異步線程池分來就須要配置兩個線程池。
調度任務添加 @Scheduled 註解, 須要異步執行的方法添加 @Async 註解java
中間遇到點小問題, 異步任務線程池老是不生效, 而是使用的調度任務線程池, 通過查文檔不斷嘗試解決了.
公司利用 slf4j 的 MDC 作鏈路跟蹤, 因此還須要添加前置操做, 使用 TaskDecorator 實現。spring
再次分享給你們以做備忘.json
代碼以下:異步
AsyncConfig.javaasync
package com.ecej.esmart.autodispatch.config; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 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.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.Map; import java.util.concurrent.Executor; @Slf4j @EnableAsync @Configuration public class AsyncConfig implements AsyncConfigurer { @Bean @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); executor.setThreadNamePrefix("async-pool-"); executor.setTaskDecorator(new MdcTaskDecorator()); executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; } class MdcTaskDecorator implements TaskDecorator { @Override public Runnable decorate(Runnable runnable) { Map<String, String> contextMap = MDC.getCopyOfContextMap(); Runnable runnable1 = new Runnable() { @Override public void run() { if (contextMap != null) { MDC.setContextMap(contextMap); } runnable.run(); } }; return runnable1; } } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (throwable, method, params) -> { log.error("異步任務異常:方法:{} 參數:{}", method.getName(), JSON.toJSONString(params)); log.error(throwable.getMessage(), throwable); }; } }
SchedulingConfig.javaide
package com.ecej.esmart.autodispatch.config; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @Slf4j @Configuration @EnableScheduling public class SchedulingConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.setTaskScheduler(taskScheduler()); } @Bean(destroyMethod = "shutdown") public ThreadPoolTaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(5); scheduler.setThreadNamePrefix("dispatch-"); scheduler.setAwaitTerminationSeconds(600); scheduler.setErrorHandler(throwable -> log.error("調度任務發生異常", throwable)); scheduler.setWaitForTasksToCompleteOnShutdown(true); return scheduler; } }