2015-11-30 20 views
8

Ho una domanda sull'annotazione di Spring @Async e su come usarlo correttamente. Diciamo che ho questi metodi:Come utilizzare correttamente @Async in primavera

@Async 
public void test(String param1) { 
    test2(param1, null); 
} 

@Async 
public void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

@Async 
public void test3(String param1, String param2, String param3) { 
    // do some heavy work 
} 

Ho bisogno di avere @Async su tutti e tre i metodi per essere chiamato in modo asincrono o è solo quanto basta per avere sul test3 che effettivamente fare il lavoro?

+0

Non ha una risposta alla mia domanda, dice solo che il blocco '' @ Async'' verrà eseguito in modo asincrono. –

risposta

3

Ne hai bisogno solo con un metodo. Solo perché, dopo l'avvio di una nuova discussione con il primo metodo @Async, è asincrono rispetto al metodo di richiamo.

Ma ciò che questo significa per te, è altamente a seconda di ciò che il vostro esempio dovrebbe illustrare:

1) Quindi nel tuo caso, un @Async per test1(String param1) è sufficiente quando si mai richiama test2 e test3 attraverso test1.

@Async 
public void test1(String param1) { 
    test2(param1, null); 
} 

private void test2(String param1, String param2) { 
    test3(param1, param2, null); 
} 

private void test3(String param1, String param2, String param3) { 
    // do something 
} 

nota che i metodi 2 e 3 sono private


2) Ma se il vostro esempio è per illustrare un metodo sovraccarico modello per parametri di default (Method chaining), allora è più complicato. Quindi dovresti avere l'annotazione @Async con il metodo che fa le cose reali. Perché si desidera eseguire l'esecuzione reale in modo asincrono, ma non una chiamata asincrona per ogni fase di concatenamento.

public void test(String param1) { 
    test(param1, null); 
} 


public void test(String param1, String param2) { 
    //this invocation runs async only when real AspectJ is used 
    test(param1, param2, null); 
} 

@Async 
public void test(String param1, String param2, String param3) { 
    // do something 
} 

nota che tutti i metodi sono denominati semplicemente test (metodo concatenamento modello)

Il problema è che Spring (senza reale load AspectJ o in fase di compilazione tessitura) non verrà eseguito un metodo asincrono se è invocato tramite this! (vedi https://stackoverflow.com/a/22561903/280244)

+0

Sì, sono in realtà metodi sovraccarichi, non so perché li ho chiamati test1, test2 e test3 qui ... Quindi, in pratica, il metodo che esegue un lavoro asincrono ('' test3'' in questo caso), deve essere pubblico per essere effettivamente asincrono (dal momento che non sto usando AspectJ)? Gli altri non dovrebbero preoccuparsi dell'annotazione? –

0

Utilizzando @Async solo sul terzo metodo test3 non è sufficiente, perché chiamare localmente causa che oggetto non viene inoltrata e solo tramite proxy oggetti (prelevato dal contenitore, ad esempio utilizzando @Autowired) ha chiamate asincrone

Anche guardare here

2

Penso che @Ralph abbia coperto le tue preoccupazioni.

Ma, come il nome della domanda è "Come usare @Async correttamente in Primavera", devo menzionare questo:

Si deve sempre cambiare (o almeno prendere in considerazione per cambiare) esecutore compito predefinito in primavera contesto o utilizzare l'esecutore di attività personalizzato.

Because:

Per default, un SimpleAsyncTaskExecutor saranno utilizzati per elaborare asincrona chiamate di metodi.

and:

NOTA: Questa implementazione non riutilizzare le discussioni! Considerare invece un'implementazione TaskExecutor thread-pooling, in particolare per che esegue un numero elevato di attività di breve durata.

Problemi correlati