2011-01-20 8 views
25

Vorrei inserire una dipendenza in un ServletContextListener. Tuttavia, il mio approccio non funziona. Vedo che Spring sta chiamando il mio metodo setter, ma in seguito quando viene chiamato contextInitialized, la proprietà è null.Spring - Iniezione di una dipendenza in un ServletContextListener

Qui è il mio set up:

Il ServletContextListener:

public class MyListener implements ServletContextListener{ 

    private String prop; 

    /* (non-Javadoc) 
    * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
    */ 
    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     System.out.println("Initialising listener..."); 
     System.out.println(prop); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
    } 

    public void setProp(String val) { 
     System.out.println("set prop to " + prop); 
     prop = val; 
    } 
} 

web.xml: (questo è l'ultimo ascoltatore nel file)

<listener> 
    <listener-class>MyListener</listener-class> 
</listener> 

applicationContext.xml:

<bean id="listener" class="MyListener"> 
    <property name="prop" value="HELLO" /> 
</bean> 

uscita:

set prop to HELLO 
Initialising listener... 
null 

Qual è il modo corretto per raggiungere questo obiettivo?

risposta

17

ho risolto questo rimuovendo il fagiolo ascoltatore e la creazione di un nuovo bean per le mie proprietà . Ho quindi utilizzato la seguente nel mio ascoltatore, per ottenere la proprietà di fagioli:

@Override 
public void contextInitialized(ServletContextEvent event) { 

    final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); 
    final Properties props = (Properties)springContext.getBean("myProps"); 
} 
+0

Il modo in cui i bean vengono istanziati rende difficile il test, vedi la mia risposta. –

-1

ServletContextListener viene creato dal server, non da Spring.

MODIFICA: AFAIK, non è possibile ottenere ciò che si sta tentando, qual è il motivo per cui si desidera impostare le variabili di istanza nell'ascoltatore?

+0

@dogbane Che cosa è che si sta cercando di fare? ServletContextListener serve per monitorare il ciclo di vita di una webapp. – saugata

5

Come accennato prima, ServletContextListener viene creato dal server e quindi non è gestito da Spring.

Se si desidera ricevere una notifica della ServletContext, è possibile implementare l'interfaccia:

org.springframework.web.context.ServletContextAware 
+0

Mi dispiace, non capisco perché ho bisogno di implementare 'ServletContextAware'? Il mio listener ha già un riferimento al 'ServletContext' perché è presente in' ServletContextEvent'. – dogbane

+0

se si utilizza il listener, non è possibile iniettare dipendenze Spring, quindi il ServletContextAware è un'alternativa –

1

non puoi avere primavera per fare che, come già dichiarato che è stato creato dal server. Se è necessario passare params al vostro ascoltatore, è possibile definire nel vostro web XML come context-param

<context-param> 
     <param-name>parameterName</param-name> 
     <param-value>parameterValue</param-value> 
    </context-param> 

E nel Listener è possibile recuperarlo come qui di seguito;

event.getServletContext().getInitParameter("parameterName") 

Edit 1:

Vedi il link sotto per un'altra possibile soluzione:

How to inject dependencies into HttpSessionListener, using Spring?

+0

Mi piacerebbe passare un bean in. Non nomi-valori. – dogbane

+0

@dogbane vedi il post modificato. Aggiunto un nuovo collegamento che potrebbe essere utile anche per il tuo caso – fmucar

28

risposta del dogbane opere (accettati), ma rende il test difficile a causa del modo in cui i fagioli sono istanziati.Io preferisco l'approccio suggerito in questo question:

@Autowired private Properties props; 

@Override 
public void contextInitialized(ServletContextEvent sce) { 
    WebApplicationContextUtils 
     .getRequiredWebApplicationContext(sce.getServletContext()) 
     .getAutowireCapableBeanFactory() 
     .autowireBean(this); 

    //Do something with props 
    ... 
}  
+3

So che questo è vecchio, ma per i futuri lettori, quando cerco di ottenere un 'IllegalStateException' con il messaggio * No WebApplicationContext trovato: nessun ContextLoaderListener registrato? * – christopher

+0

Chris: Ottengo lo stesso problema! –

+0

Questo ha funzionato per me..grazie abd –

Problemi correlati