metodi asincroni in spring
TRANSCRIPT
![Page 1: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/1.jpg)
Metodi asincroni in SpringVitalij Zadneprovskij
ROME 24-25 MARCH 2017
![Page 2: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/2.jpg)
JUG Roma e Code Garden
![Page 3: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/3.jpg)
![Page 4: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/4.jpg)
![Page 5: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/5.jpg)
I processi del sistema operativo
● Istanza di programma in esecuzione
● Comunicazione limitata
● JVM è un processo, di solito
![Page 6: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/6.jpg)
Thread nel sistema operativo
● Eseguono istruzioni in modo concorrente
● Condividono dati
Fonte immagine: wikipedia.org
![Page 7: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/7.jpg)
Thread in Java
● Un main thread può lanciarne altri
● Istanza classe Thread
● Ogni thread ha una sua pila di chiamate
Fonte immagine: http://blog.takipi.com
![Page 8: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/8.jpg)
Ciclo di vita di un thread di Java
Fonte immagine: https://www.tutorialspoint.com
![Page 9: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/9.jpg)
Lancio di un threadpublic class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
![Page 10: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/10.jpg)
![Page 11: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/11.jpg)
Thread pool
● Allocare e liberare memoria degrada le prestazioni
● È meglio fare riuso di thread● Un thread usato torna nel pool● Numero di thread nel pool può essere
fisso o variabile
![Page 12: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/12.jpg)
Interfaccia Executor
● Astrazione per la gestione dei thread pool● Unico metodo:
void execute(Runnable command);
Che ha un funzionamento simile a:
(new Thread(runnable)).start();
● Astrazione sulla gestione del thread pool
![Page 13: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/13.jpg)
Esempio didattico di Executor
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
![Page 14: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/14.jpg)
Executor in pratica
● Conviene delegare la gestione dei pool di thread al container
● Oppure usare ThreadPoolExecutor e ScheduledThreadPoolExecutor
![Page 15: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/15.jpg)
Interfaccia Callable
public interface Callable<V> {
V call() throws Exception;
}
● Restituisce un valore del tipo che vogliamo noi
● Può lanciare eccezioni al chiamante
![Page 16: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/16.jpg)
Future
Fonte immagine: boardgamegeek.com
![Page 17: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/17.jpg)
Future
● Rappresenta una computazione● Può essere in corso, eseguita o annullata● Chiamando il metodo get() metto in
waiting il thread chiamante
![Page 18: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/18.jpg)
Interfaccia Futurepublic interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
![Page 19: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/19.jpg)
Si può fare di meglio
![Page 20: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/20.jpg)
Le callback● Quando il metodo
asincrono termina, ne chiama un altro
● Metodi distinti in caso di successo o errore
Lana Turner
![Page 21: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/21.jpg)
ListenableFuture di Spring Corepublic interface ListenableFuture<T> extends Future<T> {
void addCallback(ListenableFutureCallback<? super T> var1);
void addCallback(SuccessCallback<? super T> var1, FailureCallback var2);
}
![Page 22: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/22.jpg)
E se la callback dovesse chiamare un’altra callback?
● Può capitare di dover fare varie chiamate consecutive
● Se non si sta attenti, si finisce per scrivere codice difficile da modificare
![Page 23: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/23.jpg)
Esempio in JavaListenableFuture<String> listenable = asyncService.listenableMethod(); listenable.addCallback(new ListenableFutureCallback<String>(){ public void onSuccess(String s) { try { ListenableFuture lf = asyncService.listenableMethod(); lf.addCallback(new ListenableFutureCallback() { public void onFailure(Throwable throwable) { try { ListenableFuture lf2 = asyncService.listenableMethod(); } catch (InterruptedException e) { logger.error(e.getLocalizedMessage(), e); } } public void onSuccess(Object o) { } }); } catch (InterruptedException e) { logger.error(e.getLocalizedMessage(), e); } } public void onFailure(Throwable throwable) {} });
![Page 24: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/24.jpg)
L’inferno delle callback
John Martin “Le Pandemonium” Louvre
![Page 25: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/25.jpg)
Facciamoci aiutare da Java 8
● Ho una classe MiaClasse che ha un metodo mioMetodo()
● Posso passare questo metodo come argomento:
MiaClasse::mioMetodo
![Page 26: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/26.jpg)
CompletableFuture di Java 8
● Passiamo i metodi come argomenti● Aggiungere callback: thenApply()
● Gestire errori: exceptionally()
● Ultimo metodo: thenAccept()
![Page 27: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/27.jpg)
Esempio di CompletableFuture
CompletableFuture<String> completableFuture = asyncService.completableMethod();
completableFuture = completableFuture.exceptionally(this::onException);
completableFuture = completableFuture.thenApply(this::intermediateMethod);
completableFuture.thenAccept(this::lastMethod);
![Page 28: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/28.jpg)
Altro esempio
CompletableFuture.supplyAsync(this::findReceiver)
.thenApply(this::sendMsg)
.thenAccept(this::notify);
![Page 29: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/29.jpg)
Arriviamo a Spring
Sandro Botticelli, “Primavera”
![Page 30: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/30.jpg)
Configurazione generale
● Da XML, dopo aver aggiunto il namespace XML “task”:
<task:annotationdriven />
● Annotation per Spring Boot:
@EnableAsync
![Page 31: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/31.jpg)
Configurazione TaskExecutor
● Di default viene usato il SimpleAsyncTaskExecutor che non riusa i thread
● Per usare il ThreadPoolTaskExecutor:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
![Page 32: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/32.jpg)
Valori di ritorno ammessi
● Future● ListenableFuture● CompletableFuture (richiede Java 8)
![Page 33: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/33.jpg)
Esempio di Future @Async
public Future<String> futureMethod(){
Future<String> future = null;
try {
Thread.sleep(1000L);
future = AsyncResult.forValue("OK");
} catch (InterruptedException e) {
logger.error(e.getLocalizedMessage(), e);
future = AsyncResult.forExecutionException(e);
}
return future;
}
![Page 34: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/34.jpg)
Esempio di ListenableFuture @Async
public ListenableFuture listenableMethod() throws InterruptedException {
ListenableFuture<String> listenableFuture = null;
try {
Thread.sleep(1000L);
listenableFuture = AsyncResult.forValue("OK");
} catch (InterruptedException e) {
logger.error(e.getLocalizedMessage(), e);
listenableFuture = AsyncResult.forExecutionException(e);
}
return listenableFuture;
}
![Page 35: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/35.jpg)
Esempio di CompletableFuture @Async
public CompletableFuture<String> completableMethod() throws InterruptedException{
CompletableFuture<String> completableFuture = new CompletableFuture<String>();
try {
Thread.sleep(1000L);
completableFuture.complete("OK");
} catch (InterruptedException e) {
logger.error(e.getLocalizedMessage(), e);
completableFuture.completeExceptionally(e);
}
return completableFuture;
}
![Page 36: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/36.jpg)
Lato Controller
● Nei vari controller, va restituito un DeferredResult
● Il DeferredResult deve essere valorizzato nella callback
● Può contenere il valore da restituire, oppure un ModelAndView
![Page 37: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/37.jpg)
Silvia Bottini, “Cry”
![Page 38: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/38.jpg)
Esempio Spring Data JPAinterface EmployeeRepository extends JpaRepository<Employee, Long> {
@Async
Future<List<Employee>> findDistinctByFirstName(String firstName);
@Async
CompletableFuture<Employee> findFirstByFirstNameIgnoreCase(String firstName);
@Async
ListenableFuture<Employee> findFirstByLastName(String lastName);
}
![Page 39: Metodi asincroni in spring](https://reader034.vdocuments.mx/reader034/viewer/2022042605/58e4a5b41a28abbb038b45d3/html5/thumbnails/39.jpg)