Tipps zu Spring Async – Teil 2

Gastbeitrag von | 06.04.2019 | Softwareentwicklung | 0 Kommentare

In Teil 2 der Tipps zu Spring Async möchte ich Ihnen beschreiben, wie Sie eine Exception mit Spring Boot und der @Async-Annotation händeln. Idealerweise sollten Sie Teil 1 gelesen haben.

Legen wir gleich los. Beim Forken eines Threads von einem Hauptthread haben Sie zwei Optionen:

1. Fire and forget: Sie forken einfach einen Thread, weisen ihm eine Aufgabe zu und vergessen ihn wieder. Sie kümmern sich nicht um das Ergebnis oder den Rückgabetyp, da Sie diese Informationen zur Ausführung der nächsten Geschäftslogik nicht benötigen. Mit einem kleinen Beispiel ist dies gut nachvollziehbar: Angenommen, Sie wollen Mitarbeitern Gehalt überweisen. Sie senden an jeden Mitarbeiter aysnchron eine E-Mail mit der entsprechenden Gehaltsabrechnung. Das Versenden des Gehaltsnachweises per E-Mail an die Mitarbeiter ist nicht Teil der Kerngeschäftslogik, sondern ein Querschnittsthema. In vielen Fällen ist dies „nice-to-have“, in manchen vielleicht ein „must-have“. Da Sie dies nicht manuell durchführen wollen, überlegen Sie sich einen Mechanismus, der das Versenden beim nächsten Mal übernimmt.

2. Fire with Callback: Hier fügen Sie dem geforkten Thread einen Callback hinzu, wodurch der Hauptthread den Callback auf das Ergebnis überprüft, da er dieses benötigt, um weiter fortfahren zu können. Beispiel: Angenommen, Sie bereiten einen Mitarbeiterbericht vor. Ihre Software speichert Mitarbeiterinformationen basierend auf der Datenkategorie in unterschiedlichen Backends. Der Allgemeine Dienst beinhaltet bspw. die allgemeinen Daten der Mitarbeiter (Name, Geburtstag, Geschlecht, Adresse) und der Finanzdienst die gehalts-, steuer- und rentenbezogenen Daten usw. In diesem Beispiel forken Sie zwei Threads parallel – einen für den Allgemeinen Service und einen für den Finanzdienst. Sie benötigen jedoch beide Datensätze, um den Bericht zu erstellen, da Sie die Daten kombinieren müssen. Für den Hauptthread bedeutet dies, dass die Ergebnisse als Callback von den Subthreads angezeigt werden müssen. Durch die Verwendung von CompletebleFuture lässt sich diese Herausforderung meistern.

Was tun Sie nun, wenn in den beiden genannten Szenarien eine Exception auftritt?

Im zweiten Szenario ist es eher einfach, da der Callback entweder erfolgreich oder eben nicht erfolgreich ist. Im Falle eines Fehlers wird die Exception innerhalb von CompltebleFuture eingeschlossen. Die Überprüfung erfolgt im Hauptthread und da dies relativ einfach funktioniert, möchte ich hier nicht im Detail darauf eingehen.

Das 1. Szenario ist etwas kniffliger, denn wie erkennen Sie, ob es sich um einen Erfolg oder einen Fehler handelt? Wie können Sie feststellen, dass etwas nicht funktioniert hat? Nun, die Antwort liegt im Exception Handling. Alles was Sie tun müssen, ist einen eigenen Exception Handler zu injizieren, um beim Auftreten einer Exception eine Async-Methode auszuführen. Dies erreichen Sie mittels AsyncConfigurer.

Der AsyncConfigurer ist ein von Spring bereitgestelltes Interface, das zwei Methoden zur Verfügung stellt: mit der einen überschreiben Sie den TaskExecutor (Threadpool) und die andere ist der Exception Handler, den Sie in einer eigenen Klasse aufrufen können. Ich möchte aber in meinem Beispiel einen anderen Weg gehen und eine AsyncConfigurerSupport Klasse verwenden, die @Configuration und @EnableAsync bereitstellt:

Bitte beachten Sie, dass ich im Falle einer getAsyncExecutor-Methode keinen neuen Executor erstelle, da ich keinen eigenen Task-Executor sondern Springs SimpleAsyncExecutor verwenden möchte. Dazu benötige ich lediglich einen benutzerdefinierten Exception Handler und erstelle einen Lambda-Ausdruck, der die AsyncUncaughtExceptionHandler-Klasse erweitert und die handleuncaughtexception-Methode überschreibt.

Auf diese Weise instruiere ich Spring beim Laden mit meinem anwendungsspezifischen AsyncConfigurer (CustomConfiguration) und Lambda-Ausdruck als Exception-Handler. Alles was ich dann benötige, ist eine @Async-Methode, die eine Ausnahme auslöst:

Als nächstes erstellen wir eine Caller-Methode:

Jetzt führen wir die Anwendung mit Spring Boot aus, und schauen, wie sie die von der Methode sendMailwithException geworfene Ausnahme abfängt.

Und als Ergebnis erhalten wir:

Hinweise: 

Der Beitrag von Shamik Mitra ist im Original unter https://dzone.com/articles/effective-advice-on-spring-async-exceptionhandler-1 erschienen. Wenn Sie Fragen oder Hinweise haben, freut sich Shamik Mitra bestimmt über Ihren Kommentar auf der Orginalseite.

Mit Zustimmung von Shamik Mitra übersetzen wir verschiedene Beiträge von ihm hier in unserem Blog vom Englischen ins Deutsche. Demnächst auch „Tipps zu Spring Async – Teil 3“.

Shamik Mitra

Shamik Mitra

Shamik Mitra ist ein selbsternannter Java Maniac. Er arbeitet als technischer Projektmanager bei Tata Consultancy Services (TCS), und war zuvor bei Cognizant als Architekt und bei IBM als technischer Leiter aktiv. Er ist der Most Valuable Blogger bei DZone und Techathon Coding Competition Jury Award Winner. Er veröffentlicht regelmäßig Tutorials bei A4Academics und er ist technischer Reviewer bei PACKT Publication. Auf vielen dieser Plattformen teilt er sein Wissen zu Java, Java EE, Hibernate, Spring, Entwurfsmuster, Micro-Service, Bigdata und Agile.

Gefällt Ihnen dieser Beitrag?

Melden Sie sich für unsere News-Updates an und erhalten Sie einmal pro Woche Tipps und Meinungen von Fachleuten direkt in Ihren Posteingang.

Gefällt Ihnen dieser Beitrag?

Share This