2012-05-01 9 views
10

Voglio avviare un thread del servizio di posta daemon sull'avvio del server tomcat. Quindi, ho annotato un metodo con annotazione @Async.Come avviare un daemon all'avvio del server in primavera

Ho una classe che implementa un'interfaccia ApplicationListener. Quando chiamo il mio metodo asincrono da questa classe, non inizia mai in modo asincrono e blocca il thread corrente. E quando chiamo il mio metodo asincrono da una classe di controller di primavera, non blocca mai e inizia in modo asincrono.

Perché il metodo asincrono viene eseguito correttamente da una classe e non dall'altra classe?

Cosa sto facendo male e Come posso eseguire il mio metodo asincrono all'avvio del server ??

Grazie in anticipo.

Edit: Hi Guys, ho provato ad utilizzare l'interfaccia InitializingBean, @PostConstruct, init-metodo di approccio per chiamare il mio metodo asincrono, ma non è mai eseguito. Poi ho capito, il mio default lazy-init è vero, quindi faccio il lazy-init a false per il mio InitializingBean. Ora esegue il mio metodo asnyc, ma blocca il thread corrente e ora un altro problema, sto affrontando è che il mio server non si è fermato con grazia, ma devo fermare il mio server con forza.

+2

Mostraci il tuo codice. –

risposta

12

Prima di tutto Non è necessario implementare l'interfaccia ApplicationListener. Stai lavorando con Spring - Il contesto dell'applicazione è sufficiente.

In secondo luogo si tratta di Spring @Async, significa che l'attività deve essere avviata dal contesto dell'applicazione e il bean controller è una parte di esso.

È necessario assicurarsi di avere <annotation-driven> nel file xml di primavera.

È possibile avviare il vostro compito sulla funzione @PostConstruct:

@Component 
public class SampleBeanImpl implements SampleBean { 

    @Async 
    void doSomething() { … } 
} 


@Component 
public class SampleBeanInititalizer { 

    @Autowired 
    private final SampleBean bean; 

    @PostConstruct 
    public void initialize() { 
    bean.doSomething(); 
    } 
} 
+0

Ciao Danny, Grazie, un'altra domanda, come posso eseguire qualche metodo all'avvio del server, Se non implementerò l'interfaccia ApplicationListener. –

+0

vedere la mia risposta aggiornata. –

+1

La soluzione accettata non funzionerà come indicato nel seguente bug: https://jira.spring.io/browse/SPR-7560 –

0

@asyn è qualcosa che fa parte del framework di primavera, Il contesto di utilizzo del vostro ascoltatore in primavera? In caso contrario, suggerirò di iniziare un nuovo thread nel tuo metodo asincrono.

4

Sulla base di reference primavera, uso di @Async ha dei limiti durante l'avvio dell'applicazione:

@Async non può essere utilizzato

in combinazione con callback del ciclo di vita come @PostConstruct. Per inizializzare in modo asincrono i bean Spring attualmente , è necessario utilizzare un bean Spring di inizializzazione separato che richiami il metodo annotato @Async sulla destinazione.

Quindi, nel tuo caso, forse sarebbe bello avere un'implementazione InitializingBean con il tuo bean di destinazione e quindi avviare il demone attraverso questo.

2

Hai aggiunto il tag <annotation-driven> al contesto dell'applicazione? Dal Spring reference doc:

Per attivare sia @Scheduled e @Async annotazioni, è sufficiente inserire l'elemento 'annotation-driven' dallo spazio dei nomi compito nella configurazione.

nota, si dovrebbe anche prendere in considerazione per configurare un esecutore esempio. Dal task schema definition:

Definisce un'istanza ThreadPoolTaskExecutor con dimensioni della piscina configurabile, coda di capacità, keep-alive, e valori di rifiuto di politica. Consultare Javadoc per l'annotazione org.springframework.scheduling.annotation.EnableAsync per informazioni sulle alternative basate su codice a questo elemento XML.

in modo da creare un esecutore che è sostenuta da un pool di thread con 5 filetti si deve effettuare le seguenti operazioni:

<task:annotation-driven executor="myExecutor"/> 
<task:executor id="myExecutor" pool-size="5"/> 

Per ulteriori opzioni di configurazione, vedere la @EnableAsync javadoc come sopra indicato.

1

il mio inglese è pool. è necessario impostare la classe di servizio @Lazy (false).

Problemi correlati