Ho un'applicazione a riga di comando che utilizza un bean gestito Primavera-che è composto da un java ExecutorService
creata con:Come arrestare correttamente i servizi di esecuzione con Spring?
ExecutorService service = Executors.newFixedThreadPool(4);
Ora, voglio il mio servizio di arresto quando la mia applicazione si chiude, così ho fatto la mia fagioli implementare l'interfaccia DisposableBean
ed avere un metodo di distruggere tali come:
public void destroy(){
service.shutdown();
}
allora potrei essere tentato di fare qualcosa di simile registrare un gancio di arresto sul contesto primavera. Tuttavia ho scoperto (nel modo più duro, cioè in una versione pre-produzione) che questo non funziona: il gancio di shutdown non viene chiamato prima che venga chiamato il metodo ExecutorService.shutdown()
, causando un classico problema di catch 22 (si ottiene chiamato su interruzione, cioè, se premo Ctrl-C mentre l'applicazione è in esecuzione). Questo è sfuggito ai miei test unitari perché per qualche motivo sembra funzionare bene all'interno di JUnit, il che mi sta ancora sconcertando: cosa fa JUnit in modo diverso?
La soluzione che ho trovato finora è chiamare esplicitamente ApplicationContext.close()
appena prima di uscire dalla mia funzione principale. Mi chiedevo se ci fosse una soluzione migliore a questo e quali sono le migliori pratiche per avere pool di thread flessibili gestiti da Spring. Inoltre, cosa succede se il mio bean è non gestito direttamente da Spring ma è creato da un bean gestito da Spring? Devo effettuare una cascata delle chiamate a destroy()
? Non sarebbe molto incline agli errori?
Apprezzo qualsiasi commento, suggerimento, ulteriore lettura, RTFM, ricette magiche.
Grazie!
PS: cosa succede se voglio spostare la mia applicazione da riga di comando su un server di app come Tomcat? Qualcosa cambia? –
Includendo il titolo e il tuo PS, contiamo * sette * (7!) Punti interrogativi. :-) Potrebbe ottenere migliori risposte se chiedi solo una domanda specifica. – Keith