gpt4 book ai didi

java - Spring Async,如何在异步任务执行器中启用请求范围

转载 作者:行者123 更新时间:2023-12-03 13:03:10 24 4
gpt4 key购买 nike

我尝试在 Spring 使用@Async,在我的服务中,我使用范围为session的bean,总是出现以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.classSession': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No session found and request already completed - cannot create new session!



如前所述,找不到 session ,请求已经完成。我实现了AsyncConfigurer以便覆盖ThreadPoolTask​​Executor:下面是我的代码

Controller :
@Autowired 
MyService myService;

@RequestMapping(value = "/doIt", method = RequestMethod.PUT)
public HttpEntity initiateCurrent(..){

myService.do();
...
}

我的服务
@Autowired 
ClassWithScopeSession classSession;

@Async("taskExecutor")
public void do(){
....
...
classSession.doService();
}

//覆盖ThreadPoolTask​​Executor
public class ContextAwareCallable<T> implements Callable<T> {
private Callable<T> task;
private RequestAttributes context;

@Autowired
private ApplicationContext appContext;

public ContextAwareCallable(Callable<T> task, RequestAttributes context) {
this.task = task;
this.context = context;
}

@Override
public T call() throws Exception {
if (context != null) {
RequestContextHolder.setRequestAttributes(context);
}
try {
return task.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}

public class ContextAwarePoolExecutor extends ThreadPoolTaskExecutor {
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(new ContextAwareCallable(task, RequestContextHolder.currentRequestAttributes()));
}

@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(new ContextAwareCallable(task, RequestContextHolder.currentRequestAttributes()));
}
}

@Configuration
@EnableAsync
public class ExecutorConfig implements AsyncConfigurer {

@Override
@Bean(name="taskExecutor")
public Executor getAsyncExecutor() {
return new ContextAwarePoolExecutor();
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}

我遵循了这个 response

最佳答案

您需要改写execute方法:

@Override
public void execute(Runnable task) {
super.execute(new ContextAwareCallable(task, RequestContextHolder.currentRequestAttributes()));
}

并将您的ContextAwareCallable更新为:
public class ContextAwareCallable implements Runnable {

private Runnable task;
private RequestAttributes context;

public ContextAwareCallable(Runnable task, RequestAttributes context) {
this.task = task;
this.context = context;
}

@Override
public void run() {
if (context != null) {
RequestContextHolder.setRequestAttributes(context);
}

task.run();
}

}

我不是专家,但是这种解决方案对我有用。

使用 @Async注释方法后,它将在 execute()类上运行 ThreadPoolTaskExecutor方法,而不是 submit()submitListenable()

在我的解决方案中,它返回 CompletableFuture。这很奇怪,因为execute不会返回任何东西。

希望它能对某人有所帮助。

关于java - Spring Async,如何在异步任务执行器中启用请求范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52593404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com