spring启动在触发异步线程后从应用程序注销

yyyllmsg  于 2021-06-08  发布在  Redis
关注(0)|答案(0)|浏览(293)

我使用模块化maven-spring引导应用程序,最近在其中添加了redis集成。为了与异步线程共享loclcontext、securitycontext和mdc上下文,我在核心maven引导项目中添加了一个decorator。

public class ContextAwareTaskDecorator 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();
    RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
    Locale locale = LocaleContextHolder.getLocale();
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    return () -> {
      try {
        // Right now: @Async thread context !
        // (Restore the Web thread context's MDC data)
        if (contextMap != null) {
          MDC.setContextMap(contextMap);
        }
        if (locale != null) {
          LocaleContextHolder.setLocale(locale, true);
        }
        if (attributes != null) {
          RequestContextHolder.setRequestAttributes(attributes, true);
        }

        if(authentication != null) {
          SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        runnable.run();
      } finally {
        MDC.clear();
        LocaleContextHolder.resetLocaleContext();
        RequestContextHolder.resetRequestAttributes();
        SecurityContextHolder.clearContext();
      }
    };
  }
}

在我的网络应用程序中注册了这个装饰器

@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

    private static final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);

    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        log.debug("Creating Async Task Executor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(300);
        executor.setQueueCapacity(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setTaskDecorator(new ContextAwareTaskDecorator());
        executor.setThreadNamePrefix("my-executor-");
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

现在,当我执行一个特定的请求时,我正在用@async触发方法,它可以正常工作,但在那之后,如果我单击任何链接或选项卡,将我从应用程序中抛出,并且我被重定向到登录页,那么在任何类型的日志中都没有错误。
我试着评论decorator中的一行,它重置了所有上下文并清除了mdc,即使在那之后我也面临同样的问题
如果我删除了redis依赖,那么一切都正常。
有人能告诉我是什么原因造成的吗??

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题