我正在尝试实现一个返回类型为Future的spring @Async任务, 但我无法弄清楚如何正确地做到这一点。
修改
从春季来源和春季参考手册:
即使是返回值的方法也可以异步调用。但是,这些方法是必需的 有一个Future类型的返回值。这仍然提供了异步执行的好处 调用者可以在调用Future上的get()之前执行其他任务。
它给出了一个例子:
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
如何正确实现?
答案 0 :(得分:22)
使用@Async
可以异步运行方法中的计算。这意味着如果它被调用(在Spring托管bean上),控件立即返回给调用者,方法中的代码在另一个线程中运行。调用者接收绑定到正在运行的计算的Future
对象,并可以使用它来检查计算是否正在运行和/或等待结果。
创建这样的方法很简单。使用@Async
对其进行注释,并将结果包装在AsyncResult
中,如博客文章中所示。
答案 1 :(得分:5)
查看此blog post
重要配置是:
在spring config中启用异步 xml通过定义:
<!-- Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. -->
<task:annotation-driven/>
默认情况下将使用SimpleAsyncTaskExecutor。
将回复包裹在未来&lt;&gt;对象
示例:
@Async
public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) {
//do some logic
return new AsyncResult<PublishAndReturnDocumentResult>(result);
}
然后您可以检查结果是否已完成(result.isDone()) 或等待获得响应result.get()
答案 2 :(得分:2)
ExecutorService可以调度Callable并返回Future对象。 Future是一个占位符,包含结果一旦可用。它允许您检查结果是否存在,取消任务,或阻止并等待结果。只有当您期望任务中的某个对象/值时,Future才有用。
进行Future调用的正确方法是:
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());
}
NextEvenNumberFinder类:
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参考手册:http://static.springsource.org/spring-integration/reference/htmlsingle/