在Spring中使用線程池執行異步任務,經過TaskDecorator進行父線程向子線程傳遞參數 (同一個線程的實現方案正常是用ThreadLocal)java
如下例子就是經過TaskDecorator實現日誌TraceID傳遞異步
@Component public class MdcFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { MDC.put("mdcData", "[userId:Duke]"); chain.doFilter(request, response); } finally { MDC.clear(); } } } @EnableAsync(proxyTargetClass = true) @SpringBootApplication public class Application extends AsyncConfigurerSupport { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setTaskDecorator(new MdcTaskDecorator()); executor.initialize(); return executor; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } class MdcTaskDecorator implements TaskDecorator { @Override public Runnable decorate(Runnable runnable) { // Right now: Web thread context ! // (Grab the current thread MDC data) Map<String, String> contextMap = MDC.getCopyOfContextMap(); return () -> { try { // Right now: @Async thread context ! // (Restore the Web thread context's MDC data) MDC.setContextMap(contextMap); runnable.run(); } finally { MDC.clear(); } }; } }