Cet article présente principalement une explication détaillée et des exemples simples d'utilisation de @Async au printemps. Les amis dans le besoin peuvent se référer à
Utilisation de @Async au printemps
Introduction : Dans la plupart des applications Java, le traitement des interactions est implémenté dans la plupart des cas par synchronisation ; cependant, lors de l'interaction avec des systèmes tiers, il est facile de provoquer une réponse lente. Dans le passé, la plupart d'entre eux utilisaient plusieurs threads pour effectuer de telles tâches. . En fait, après Spring 3.x, @Async a été intégré pour résoudre parfaitement ce problème. Cet article présentera complètement l'utilisation de @Async.
1. Qu'est-ce qu'un appel asynchrone ?
Avant d'expliquer les appels asynchrones, examinons d'abord la définition des appels synchrones ; la synchronisation signifie que l'ensemble du processus de traitement est exécuté séquentiellement, et lorsque chaque processus est terminé, les résultats sont renvoyés. L'appel asynchrone envoie uniquement les instructions d'appel, et l'appelant n'a pas besoin d'attendre que la méthode appelée soit complètement exécutée, il continue d'exécuter le processus suivant ;
Par exemple, dans un certain appel, trois méthodes de processus A, B et C doivent être appelées séquentiellement ; si ce sont toutes des appels synchrones, elles doivent être exécutées séquentiellement avant que l'exécution du processus ne soit terminée ; Si B est une méthode d'appel asynchrone, après avoir exécuté A, l'appel de B n'attend pas la fin de B, mais commence l'exécution et appelle C. Une fois C exécuté, cela signifie que le processus est terminé.
2. Méthodes conventionnelles de traitement des appels asynchrones
En Java, lorsqu'il s'agit de scénarios similaires, elles sont généralement basées sur la création de threads indépendants pour compléter les passes logiques d'appel asynchrones correspondantes. le processus d'exécution entre le thread principal et différents threads, de sorte qu'après le démarrage d'un thread indépendant, le thread principal continue de s'exécuter sans stagner ni attendre.
3. Introduction à @Async
Au Spring, les méthodes basées sur l'annotation @Async sont appelées méthodes asynchrones ; thread, l’appelant n’a pas besoin d’attendre sa fin avant de poursuivre d’autres opérations.
Comment activer @Async au printemps
Activation basée sur la configuration Java :
@Configuration @EnableAsync public class SpringAsyncConfig { ... }
Basée sur la configuration XML La méthode d'activation du fichier est configurée comme suit :
<task:executor id="myexecutor" pool-size="5" /> <task:annotation-driven executor="myexecutor"/>
Voici les deux méthodes de définition.
4. Appelez
basé sur @Async sans valeur de retour. L'exemple est le suivant :
@Async //标注使用 public void asyncMethodWithVoidReturnType() { System.out.println("Execute method asynchronously. " + Thread.currentThread().getName()); }
utilisé La méthode est très simple, et une seule étiquette peut résoudre tous les problèmes.
5. Appel basé sur la valeur de retour @Async
Les exemples sont les suivants :
@Async public Future<String> asyncMethodWithReturnType() { System.out.println("Execute method asynchronously - " + Thread.currentThread().getName()); try { Thread.sleep(5000); return new AsyncResult<String>("hello world !!!!"); } catch (InterruptedException e) { // } return null; }
À partir de l'exemple ci-dessus, vous pouvez constater que le type de données renvoyé est le type Future, qui est une interface. Le type de résultat spécifique est AsyncResult, auquel il faut prêter attention.
Exemple d'appel d'une méthode asynchrone qui renvoie un résultat :
public void testAsyncAnnotationForMethodsWithReturnType() throws InterruptedException, ExecutionException { System.out.println("Invoking an asynchronous method. " + Thread.currentThread().getName()); Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType(); while (true) { ///这里使用了循环判断,等待获取结果信息 if (future.isDone()) { //判断是否执行完毕 System.out.println("Result from asynchronous process - " + future.get()); break; } System.out.println("Continue doing something else. "); Thread.sleep(1000); } }
Analyse : celles-ci obtiennent les informations de résultat de la méthode asynchrone via Ceci est obtenu en vérifiant constamment l'état de Future pour savoir si la méthode asynchrone actuelle a été exécutée.
6. Mécanisme de gestion des exceptions basé sur les appels @Async
Dans une méthode asynchrone, si une exception se produit, il est impossible pour l'appelant de Perceived. Si la gestion des exceptions est effectivement requise, gérez-la comme suit :
1. Personnalisez l'exécuteur de tâches qui implémente AsyncTaskExecutor
Définissez ici la logique et la méthode de gestion des exceptions spécifiques.
2. Configurez un TaskExecutor personnalisé pour remplacer l'exécuteur de tâches intégré
Exemple d'étape 1, TaskExecutor personnalisé
public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor { private AsyncTaskExecutor executor; public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) { this.executor = executor; } ////用独立的线程来包装,@Async其本质就是如此 public void execute(Runnable task) { executor.execute(createWrappedRunnable(task)); } public void execute(Runnable task, long startTimeout) { /用独立的线程来包装,@Async其本质就是如此 executor.execute(createWrappedRunnable(task), startTimeout); } public Future submit(Runnable task) { return executor.submit(createWrappedRunnable(task)); //用独立的线程来包装,@Async其本质就是如此。 } public Future submit(final Callable task) { //用独立的线程来包装,@Async其本质就是如此。 return executor.submit(createCallable(task)); } private Callable createCallable(final Callable task) { return new Callable() { public T call() throws Exception { try { return task.call(); } catch (Exception ex) { handle(ex); throw ex; } } }; } private Runnable createWrappedRunnable(final Runnable task) { return new Runnable() { public void run() { try { task.run(); } catch (Exception ex) { handle(ex); } } }; } private void handle(Exception ex) { //具体的异常逻辑处理的地方 System.err.println("Error during @Async execution: " + ex); } }
Analyse : on peut constater qu'il implémente AsyncTaskExecutor, en utilisant des threads indépendants pour effectuer des opérations de méthode spécifiques. Dans createCallable et createWrapperRunnable, la méthode et le mécanisme de gestion des exceptions sont définis.
handle() est l'endroit où nous devons nous concentrer sur la gestion des exceptions à l'avenir.
Contenu du fichier de configuration :
<task:annotation-driven executor="exceptionHandlingTaskExecutor" scheduler="defaultTaskScheduler" /> <bean id="exceptionHandlingTaskExecutor" class="nl.jborsje.blog.examples.ExceptionHandlingAsyncTaskExecutor"> <constructor-arg ref="defaultTaskExecutor" /> </bean> <task:executor id="defaultTaskExecutor" pool-size="5" /> <task:scheduler id="defaultTaskScheduler" pool-size="1" />
Analyse : La configuration ici utilise un taskExecutor personnalisé pour remplacer le TaskExecutor par défaut.
7. Mécanisme de traitement des transactions dans les appels @Async
Les méthodes marquées avec @Async sont également marquées avec @Transactional lorsqu'une opération de base de données est appelée ; , le contrôle de gestion des transactions ne sera pas disponible car il s'agit d'une opération basée sur un traitement asynchrone.
Alors comment ajouter la gestion des transactions à ces opérations ? Les méthodes qui nécessitent des opérations de gestion des transactions peuvent être placées dans la méthode asynchrone, et @Transactional.
est ajouté à la méthode appelée en interne. Par exemple : la méthode A est marquée avec @Async/@Transactional, mais une transaction ne peut pas le faire. être générés à des fins de contrôle.
La méthode B est annotée avec @Async. C et D sont appelés en B. C/D sont annotés respectivement avec @Transactional, ce qui peut atteindre l'objectif de contrôle des transactions.
8. Résumé
Grâce à la description ci-dessus, nous devrions connaître les méthodes et les précautions d'utilisation de @Async.
Ce qui précède est une explication détaillée et des exemples simples d'utilisation de @Async au printemps. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !