2015-01-09 11 views
6

Ho un listener di applicazioni che dovrebbe essere eseguito solo una volta per l'avvio webapp, poiché carica i dati di base dell'utente.Spring ApplicationListener viene attivato due volte su webapp

public class DefaultUsersDataLoader implements ApplicationListener<ContextRefreshedEvent> { 
    @Override 
    @Transactional 
    public void onApplicationEvent(ContextRefreshedEvent e) {...} 
} 

In qualche modo, viene eseguito due volte: all'avvio dell'app e quando arriva la prima richiesta al server. Perché sta succedendo questo e come posso prevenirlo?

+0

postale web.xml .... – Braj

+0

Ho avuto lo stesso problema. La rimozione di @EventListener ha risolto il problema. Qualcuno avrebbe una spiegazione? –

risposta

11

Generalmente in un'applicazione Spring MVC si dispone sia di uno ContextLoaderListener e di DispatcherServlet. Entrambi i componenti creano il proprio ApplicationContext che a loro volta sparano entrambi a ContextRefreshedEvent.

Il DispatcherServlet utilizza lo ApplicationContext come creato dallo ContextLoaderListener come genitore. Gli eventi attivati ​​dai contesti secondari vengono propagati al contesto padre.

Ora se si dispone di un ApplicationListener<ContextRefreshedEvent> definito nel contesto radice (quello caricato da ContextLoaderListener) riceverà un evento due volte.

+5

Grazie. L'ho escluso con un 'e.getApplicationContext(). GetParent()! = Null', ma sembra un po 'hacky. Mi chiedo se ci sia una pratica migliore in giro? –

+0

Non proprio, è possibile attivare un valore booleano se il listener è già stato richiamato. Se è solo per caricare alcuni dati e si utilizza Spring 4.1, è possibile utilizzare anche ['SmartInitializingSingleton'] (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans /factory/SmartInitializingSingleton.html). –

+0

Si consiglia inoltre di assicurarsi che il contesto Web non crei un'istanza di bean diversi dai controller. Ad esempio, imponi ai pacchetti base di scansione dei componenti di includere solo un pacchetto "web", che è padre dei controllori e di altri bean di questo tipo. Questo dovrebbe garantire che il listener esista solo nel contesto di root e quindi raccoglierà solo gli eventi di contesto root. – Steve

0

Non annotato il metodo del vostro ascoltatore Class con @EventListener

Problemi correlati