2010-07-02 10 views
9

Ho un ApplicationContext Spring in cui dichiaro il bean del server Jetty e lo avvio. All'interno del jetty ho un DispatcherServlet e un paio di controller. Come fare che DispatcherServlet e i suoi controllori usino i bean dallo stesso ApplicationContext dove viene dichiarato Jetty?Come incorporare Jetty in Spring e far sì che usi lo stesso AppContext in cui è stato incorporato?

Infatti, in quel contesto esterno ho un paio di bean daemon e le loro dipendenze. I controller all'interno di Jetty usano le stesse dipendenze, quindi vorrei evitare di duplicarli all'interno e all'esterno di Jetty.

risposta

5

Ho fatto un po 'di tempo fa.

Spring documentation suggerisce di utilizzare ContextLoaderListener per caricare il contesto dell'applicazione per servlet. Invece di questa lezione di primavera, usa il tuo ascoltatore. La cosa fondamentale qui è che il listener personalizzato può essere definito nella configurazione di Spring e può essere a conoscenza del contesto dell'applicazione in cui è definito; quindi, invece di caricare un nuovo contesto applicativo, restituisce semplicemente quel contesto.

L'ascoltatore sarebbe simile a questa:

public class CustomContextLoaderListener extends ContextLoaderListener implements BeanFactoryAware { 

    @Override 
    protected ContextLoader createContextLoader() { 
     return new DelegatingContextLoader(beanFactory); 
    } 

    protected BeanFactory beanFactory; 

    @Override 
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
     this.beanFactory = beanFactory; 
    } 

} 

e la DelegatingContextLoader fa questo:

public class DelegatingContextLoader extends ContextLoader { 

    protected BeanFactory beanFactory; 

    public DelegatingContextLoader(BeanFactory beanFactory) { 
     this.beanFactory = beanFactory; 
    } 

    @Override 
    protected WebApplicationContext createWebApplicationContext(ServletContext servletContext, ApplicationContext parent) throws BeansException { 
     return new GenericWebApplicationContext((DefaultListableBeanFactory) beanFactory); 
    } 

} 

E 'un po' disordinato, e probabilmente può essere migliorato, ma questo ha funzionato per me.

+1

Grazie! Dopo alcune modifiche ho risolto il mio problema. Con questa soluzione ho ottenuto l'eccezione 'ApplicationEventMulticaster non inizializzata', perché quel' GWAC' non è stato aggiornato, ma quando ho chiamato 'refresh()' su di esso, ho ottenuto un'eccezione sui postprocessori che sono stati chiamati la seconda volta. Quindi invece di usare 'GWAC' ho creato una classe' WrapperWebApplicationContext' che delegava tutte le chiamate a 'ApplicationContext' passate nel costruttore. Ora funziona perfettamente. Inoltre, ho eseguito l'override di 'createWebApplicationContext' di' ContextLoaderListener' - in questo modo non è necessario utilizzare la classe 'ContextLoader'. – Fixpoint

+0

Ok. Sono perplesso. Come si ottiene il contenitore servlet per utilizzare il bean Listener definito nella propria configurazione di primavera, invece di creare una nuova istanza che non conosce nulla su applicationContext/beanFactory? – CupawnTae