Home  >  Article  >  Java  >  How to Enable Request Scope in Asynchronous Task Execution?

How to Enable Request Scope in Asynchronous Task Execution?

DDD
DDDOriginal
2024-10-31 02:31:02462browse

How to Enable Request Scope in Asynchronous Task Execution?

Enabling Request Scope in Asynchronous Task Execution

Problem:

Asynchronous web services need to access request-scoped beans within their asynchronous processing, particularly those annotated with @Scope(value = WebApplicationContext.SCOPE_REQUEST). However, SimpleAsyncTaskExecutor does not preserve thread-bound request attributes, leading to exceptions.

Solution:

To enable request scope in asynchronous task execution, a custom TaskPoolExecutor is created along with a special Callable that stores and clears the request context for the background thread.

Implementation:

Custom Executor:

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

Context-Aware Callable:

<code class="java">public class ContextAwareCallable<T> implements Callable<T> {
    private Callable<T> task;
    private RequestAttributes context;

    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();
        }
    }
}</code>

Configuration Override:

<code class="java">@Configuration
public class ExecutorConfig extends AsyncConfigurerSupport {
    @Override
    @Bean
    public Executor getAsyncExecutor() {
        return new ContextAwarePoolExecutor();
    }
}</code>

Usage:

<code class="java">taskExecutor.execute(new ContextAwareCallable(new Runnable() {
    @Override
    public void run() {
        asyncRequest(request);
    }
}), RequestContextHolder.currentRequestAttributes());</code>

Notes:

  • This method only supports request and session scopes, not security contexts.
  • It is compatible with both Callable and Runnable interfaces.

The above is the detailed content of How to Enable Request Scope in Asynchronous Task Execution?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn