2010-08-11 20 views
7

Avere un'applicazione di primavera (app in realtà Grails) che esegue il server apache-activemq come bean spring e un paio di route apache-cammello. L'applicazione va in ibernazione per funzionare con il database. Il problema è semplice Activemq + Camel avvia BEFORE grails inserisce metodi speciali negli oggetti del dominio di ibernazione (in realtà salva/aggiorna i metodi, ecc.). Quindi, se activemq ha già alcuni dati all'avvio - il cammello inizia ad elaborare i messaggi senza utilizzare metodi DAO per i graal. Questo fallisce con grails.lang.MissingMethodException. È necessario ritardare l'avvio di activemq/camel prima che Grails inietti metodi speciali negli oggetti del dominio.Come ritardare l'avvio dei bean a molla?

risposta

4

si può spostare MQ managment in un plugin? Aumenterebbe la modularità e se dichiari in plug-descriptor

def loadAfter = ['hibernate'] 

si dovrebbe avere il comportamento desiderato. Funziona per JBPM plugin

+0

Beh, sinceramente NON creerei/manterrò plug-in separato solo per avviare AMQ dopo aver caricato l'ibernazione. Sono sicuro che c'è modo migliore. – Archer

+0

I plug in well in grails sono componenti. Ho sviluppato diversi plugin per app solo perché pensavo che sarebbero stati meglio modularizzati. I plugin sono anche un modo utile per integrare dati o sistemi legacy. Li mantieni mentre mantieni l'app. Non devi liberarli in natura. – Sammyrulez

+0

Ce l'ho;) Ma in ogni caso - NON spostarei il singolo file di inizializzazione activemq.xml dall'app principale in un altro 'componente' con la struttura completa del progetto del plugin Grails, lo postò in svn e manterrò un altro gruppo di fonti solo per ritardare l'inizializzazione di AMQ. C'è un modo più semplice. Proprietà 'start' del supporto dei bean AMQ che indica se deve essere avviato automaticamente o meno. Lo userà come adesso. – Archer

4

se tutti questi sono definiti come fagiolo di primavera, è possibile utilizzare

<bean id="activeMqBean" depends-on="anotherBean" /> 

Questo farà in modo anotherBean viene inizializzato prima activeMqBean

+0

Grazie Bonzo, ma conosco la dichiarazione "dipende da". Sfortunatamente non funzionerà come l'inizializzazione di Grails è su un livello diverso da quello di Spring. Quindi non c'è nessun bean su cui activemq dovrebbe fare affidamento. – Archer

3

Non sono sicuro nel tuo caso, ma il caricamento lento può anche aiutare ad es.

<bean id="lazybean" class="com.xxx.YourBean" lazy-init="true"> 

Un fagiolo pigro-inizializzato indica al contenitore IoC per creare un'istanza bean prima volta che viene richiesto. Questo può aiutarti a ritardare il caricamento dei fagioli che desideri.

+0

Anche questo non funzionerà, dato che il mio bean DAO è sicuramente richiesto PRIMA che hibernate sia caricato. – Archer

0

So che questa domanda è piuttosto vecchia, ma ora sto affrontando lo stesso problema nell'anno 2015 - e questo thread non offre una soluzione per me.

Mi è venuto in mente un bean di elaborazione personalizzato con CountDownLatch, che eseguo il conto alla rovescia dopo aver avviato l'applicazione. Quindi i messaggi saranno inattivi fino a quando l'app non sarà completamente avviata e funzionerà per me.

/** 
* bootstrap latch processor 
*/ 
@Log4j 
class BootstrapLatchProcessor implements Processor { 
    private final CountDownLatch latch = new CountDownLatch(1) 

    @Override 
    void process(Exchange exchange) throws Exception { 

     if(latch.count > 0){ 
      log.info "waiting for bootstrapped @ ${exchange.fromEndpoint}" 
      latch.await() 
     } 

     exchange.out = exchange.in 
    } 

    /** 
     * mark the application as bootstrapped 
     */ 
    public void setBootstrapped(){ 
     latch.countDown() 
    } 
} 

quindi utilizzarlo come un fagiolo nella propria applicazione e chiamare il metodo setBootstrapped nel vostro Bootstrap.groovy

Poi, nel tuo RouteBuilder si mette il processore tra il punto finale e la destinazione per tutte le rotte che ci si aspetta i messaggi provenienti prima che l'app sia stata avviata:

from("activemq:a.in ").processRef('bootstrapProcessor').to("bean:handlerService?method=handle") 
Problemi correlati