Async kommentiert eine Methode, so dass sie asynchron aufgerufen wird.
@org.springframework.stereotype.Service
public class MyService {
@org.springframework.scheduling.annotation.Async
void DoSomeWork(String url) {
[...]
}
}
So Spring könnte tun, müssen Sie definieren, wie ausgeführt wird. Zum Beispiel:
<task:annotation-driven />
<task:executor id="executor" pool-size="5-10" queue-capacity="100"/>
diese Weise, wenn Sie service.DoSomeWork („Parameter“) der Anruf Anruf in die Warteschlange des Testamentsvollstreckers gesetzt wird asynchron aufgerufen werden. Dies ist nützlich für Aufgaben, die gleichzeitig ausgeführt werden können.
Sie können Async verwenden, um jede Art von asynchroner Task auszuführen. Wenn Sie eine Aufgabe regelmäßig aufrufen möchten, können Sie @Scheduled verwenden (und task: scheduler statt task: executor verwenden). Sie sind vereinfachte Möglichkeiten, Java-Runnables aufzurufen.
DeferredResult <> wird verwendet, um auf eine Petition zu antworten, ohne den HTTP-Thread von Tomcat zu blockieren, der zur Beantwortung verwendet wird. Normalerweise wird der Rückgabewert für eine responseBody-Methode mit Annotationen angegeben.
@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;
}
}
Im vorherigen Beispiel fehlt eine wichtige Sache, und es ist, dass nicht zeigen, wie das latente Ergebnis eingestellt werden soll. In einer anderen Methode (wahrscheinlich der setValue-Methode) wird es ein result.setResult (value) geben. Nach dem Aufruf von setResult Spring wird die onCompletion-Prozedur aufgerufen und die Antwort an die HTTP-Anforderung zurückgegeben (siehe https://en.wikipedia.org/wiki/Push_technology#Long_polling).
Aber wenn Sie gerade den setValue synchron ausführen, gibt es keinen Vorteil bei der Verwendung eines verzögerten Ergebnisses. Hier ist Async in der Hand. Sie können eine asynchrone Methode verwenden, um den Rückgabewert zu einem späteren Zeitpunkt mit einem anderen Thread festzulegen.
@org.springframework.scheduling.annotation.Async
void SetValue(DeferredResult<String> result) {
String value;
// Do some time consuming actions
[...]
result.setResult(value);
}
Async ist nicht erforderlich, um ein verzögertes Ergebnis zu verwenden, es ist nur eine Möglichkeit, dies zu tun.
Im Beispiel gibt es eine Warteschlange mit verzögerten Ergebnissen, bei der z. B. eine geplante Aufgabe überwacht werden könnte, um ihre ausstehenden Anforderungen zu verarbeiten. Sie können auch einen nicht blockierenden Mechanismus verwenden (siehe http://en.wikipedia.org/wiki/New_I/O), um den Rückgabewert festzulegen.
Um das Bild zu vervollständigen, könnten Sie Informationen über Java-Standard-Futures (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html) und Callables (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html) suchen, die Spring DefredredResult und Async ähnlich sind.
Können Sie 'service.setValue (result) erklären; // Setzt den Wert! ', Was bedeutet' service'? – coderz
Schauen Sie sich den Code danach an. Dort finden Sie ein Beispiel dafür, wie Sie die setValue-Methode implementieren sollten. –
Warum brauchen Sie die Liste "suspendedResults"? Verfolgt Spring nicht die verzögerten Objekte? Wenn Sie das Ergebnis für ein bestimmtes Deferred-Ergebnis in SetValue festlegen, sehe ich nicht, warum diese Liste der verzögerten Objekte erforderlich ist –