Reputation: 1969
I am trying to implement a spring @Async task which has a return type of Future, but I can't really figure out how to do it properly.
EDIT
From spring source and spring refrence manual :
Even methods that return a value can be invoked asynchronously. However, such methods are required to have a Future typed return value. This still provides the benefit of asynchronous execution so that the caller can perform other tasks prior to calling get() on that Future.
and the it gives an example like so :
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
How to implement this correctly ?
Upvotes: 23
Views: 45598
Reputation: 1300
Check out this blog post.
Important configuration is:
@Async
on Spring managed bean method.<!--
Enables the detection of @Async and @Scheduled annotations
on any Spring-managed object.
-->
<task:annotation-driven />
SimpleAsyncTaskExecutor will be used by default.
Wrap the response in a Future<>
object.
@Async
public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) {
// do some logic
return new AsyncResult<PublishAndReturnDocumentResult>(result);
}
You can then check if the result is done using result.isDone()
or wait to get the response result.get()
.
Upvotes: 10
Reputation: 63409
Check out this blog post.
Using @Async
allows you to run a computation in a method asynchronously. This means that if it's called (on a Spring managed bean), the control is immediately returned to the caller and the code in the method is run in another thread. The caller receives a Future
object that is bound to the running computation and can use it to check if the computation is running and/or wait for the result.
Creating such a method is simple. Annotate it with @Async
and wrap the result in AsyncResult
, as shown in the blog post.
Upvotes: 30
Reputation: 56
The ExecutorService can schedule Callable and return a Future object. The Future is a placeholder that contains result once it's available. It allows you to check if result is there, cancel the task, or block and wait for the results. The Future is useful only when you are expecting some object/value from the task.
Correct way to do the Future call is:
Future<Integer> futureEvenNumber = executorService.submit(new NextEvenNumberFinder(10000));
// Do something.
try {
Integer nextEvenNumber = futureEvenNumber.get();
} catch (ExecutionException e) {
System.err.println("NextEvenNumberFinder threw exception: " + e.getCause());
}
The NextEvenNumberFinder class:
public class NextEvenNumberFinder implements Callable<Integer> {
private int number;
public NextEvenNumberFinder(int number) { this.number = number; }
@Override
public Integer call() throws Exception {
for (;;)
if (isEvenNumber(++number)) return number;
}
}
Spring Integration Reference Manual: http://static.springsource.org/spring-integration/reference/htmlsingle/
Upvotes: 2