我尝试使用@Async
的despring,在我的服务中,我使用范围为session
的bean,总是出现以下错误:
org.springframework.beans.factory.BeanCreationException:错误 创建名称为“ scopedTarget.classSession”的bean: 作用域“会话”对当前线程无效;考虑 如果要引用它,则为此bean定义作用域代理 从单身嵌套的异常是java.lang.IllegalStateException: 找不到会话,请求已完成-无法创建新会话 会议!
如前所述,找不到会话,请求已完成。我实现了AsyncConfigurer以便覆盖ThreadPoolTaskExecutor:下面是我的代码
控制器:
@Autowired
MyService myService;
@RequestMapping(value = "/doIt", method = RequestMethod.PUT)
public HttpEntity initiateCurrent(..){
myService.do();
...
}
MyService
@Autowired
ClassWithScopeSession classSession;
@Async("taskExecutor")
public void do(){
....
...
classSession.doService();
}
///覆盖ThreadPoolTaskExecutor
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
答案 0 :(得分:0)
我有一个带有异步方法的多租户应用程序。有人返回 CompletableFuture。 如前所述,现在它对我有用!
@Configuration
@EnableAsync 公共类 DashBoardAsyncExecutorConfig {
@Bean("MyTaskExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ContextAwarePoolExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(500);
executor.setAllowCoreThreadTimeOut(true);
executor.setThreadNamePrefix("thread");
executor.initialize();
return executor;
}
}
公共类 ContextAwarePoolExecutor 扩展了 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()));
}
//FOR COMPLETABLE FUTURE
@Override
public void execute(Runnable task) {
super.execute(new ContextAwareCallableRunnable(task, RequestContextHolder.currentRequestAttributes()));
}
}
public class ContextAwareCallableRunnable<T> implements Runnable {
private Runnable task;
private RequestAttributes context;
public ContextAwareCallableRunnable(Runnable task, RequestAttributes context) {
this.task = task;
this.context = context;
}
@Override
public void run() {
if (context != null) {
RequestContextHolder.setRequestAttributes(context);
}
task.run();
}
}