Ответ 1
Async аннотирует метод, поэтому он будет вызываться асинхронно.
@org.springframework.stereotype.Service
public class MyService {
@org.springframework.scheduling.annotation.Async
void DoSomeWork(String url) {
[...]
}
}
Итак, Spring может сделать это, вам нужно определить, как это будет выполняться. Например:
<task:annotation-driven />
<task:executor id="executor" pool-size="5-10" queue-capacity="100"/>
Таким образом, когда вы вызываете service.DoSomeWork( "параметр" ), вызов помещается в очередь исполнителя, который вызывается асинхронно. Это полезно для задач, которые могут выполняться одновременно.
Вы можете использовать Async для выполнения любой асинхронной задачи. Если вы хотите периодически вызывать задачу, вы можете использовать @Scheduled (и использовать задачу: планировщик вместо задачи: executor). Это упрощенные способы вызова java Runnables.
DeferredResult < > используется для ответа на петицию, не блокируя поток HTTP Tomcat, используемый для ответа. Обычно это будет возвращаемое значение для аннотированного метода ResponseBody.
@org.springframework.stereotype.Controller
{
private final java.util.concurrent.LinkedBlockingQueue<DeferredResult<String>> suspendedRequests = new java.util.concurrent.LinkedBlockingQueue<>();
@RequestMapping(value = "/getValue")
@ResponseBody
DeferredResult<String> getValue() {
final DeferredResult<String> result = new DeferredResult<>(null, null);
this.suspendedRequests.add(result);
result.onCompletion(new Runnable() {
@Override
public void run() {
suspendedRequests.remove(result);
}
});
service.setValue(result); // Sets the value!
return result;
}
}
В предыдущем примере отсутствует одна важная вещь, и это не показывает, как будет установлен отложенный результат. В каком-то другом методе (вероятно, метод setValue) будет создан result.setResult(значение). После вызова setResult Spring будет вызывать процедуру onCompletion и вернуть ответ на HTTP-запрос (см. https://en.wikipedia.org/wiki/Push_technology#Long_polling).
Но если вы просто выполняете setValue синхронно, нет никакого преимущества в использовании отложенного результата. Здесь есть Async. Вы можете использовать метод async для установки возвращаемого значения в какой-то момент в будущем с помощью другого потока.
@org.springframework.scheduling.annotation.Async
void SetValue(DeferredResult<String> result) {
String value;
// Do some time consuming actions
[...]
result.setResult(value);
}
Async не нужен для использования отложенного результата, его только один способ сделать это.
В примере есть очередь отложенных результатов, которые, например, можно было планировать задание для обработки ожидающих запросов. Также вы можете использовать некоторый механизм блокировки (см. http://en.wikipedia.org/wiki/New_I/O), чтобы установить возвращаемое значение.
Чтобы завершить изображение, вы можете найти информацию о стандартных фьючерсах java (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html) и callables (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html), которые в некоторой степени эквивалентны Spring DeferredResult и Async.