Spring 3.2. Задача @Async с возвращаемым типом будущего.
Я пытаюсь реализовать задачу spring @Async, которая имеет тип возврата Future,
но я не могу понять, как это сделать правильно.
- Что я получу от этого? у меня теперь будет контроль над моей задачей, чтобы я мог остановить ее и запустить?
- Есть ли какая-то эталонная реализация того, как я могу это сделать? springsource не предоставляет никаких.
ИЗМЕНИТЬ
Из spring источника и spring справочника refrence:
Даже те методы, которые возвращают значение, могут быть вызваны асинхронно. Однако такие методы необходимы для получения возвращаемого значения в будущем. Это все еще обеспечивает преимущество асинхронного выполнения, так что вызывающий может выполнять другие задачи до вызова get() в этом Будущем.
и он дает пример:
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
Как это реализовать правильно?
Ответы
Ответ 1
Отметьте этот пост в блоге.
Использование @Async
позволяет выполнить вычисление в методе асинхронно. Это означает, что если он вызвал (на Spring управляемый bean), элемент управления немедленно возвращается вызывающему, а код в методе запускается в другом потоке. Вызывающий получает объект Future
, который привязан к текущему вычислению и может использовать его для проверки того, выполняется ли вычисление и/или ждет результата.
Создание такого метода прост. Аннотировать его с помощью @Async
и обернуть результат в AsyncResult
, как показано в сообщении в блоге.
Ответ 2
ExecutorService может планировать Callable и возвращать объект 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 Справочное руководство по интеграции: http://static.springsource.org/spring-integration/reference/htmlsingle/
Ответ 3
Отметьте это сообщение в блоге
Важная конфигурация:
- @Async в spring управляемом bean методе
-
Включить async в конфигурации spring xml, определяя:
<!-- Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. -->
<task:annotation-driven/>
SimpleAsyncTaskExecutor будет использоваться по умолчанию.
Оберните ответ в объекте Future < >
Пример:
@Async
public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) {
//do some logic
return new AsyncResult<PublishAndReturnDocumentResult>(result);
}
Затем вы можете проверить, завершен ли результат (result.isDone())
или подождите, чтобы получить ответ result.get()