2010-08-11 4 views
7

Avoir une application de printemps (en fait, l'application Grails) qui exécute le serveur apache-activemq comme un haricot de printemps et deux routes apache-chameau. Application utilise hibernate pour travailler avec la base de données. Le problème est simple. Activemq + Camel démarre BEFORE grails injecte des méthodes spéciales dans les objets de domaine hibernate (en fait enregistrer/mettre à jour les méthodes etc). Donc, si activemq a déjà des données au démarrage - camel commence à traiter les messages sans avoir de méthodes DAO de grails injectées. Cela échoue avec grails.lang.MissingMethodException. Doit retarder le démarrage d'activemq/camel avant que Grails injecte des méthodes spéciales dans les objets de domaine.Comment retarder le démarrage des haricots de printemps?

Répondre

4

pouvez vous déplacer dans MQ managment un plug-in? Cela augmenterait la modularité et si vous déclarez dans le descripteur de plugin

def loadAfter = ['hibernate'] 

vous devriez avoir le comportement désiré. Fonctionne pour JBPM plugin

+0

Eh bien, honnêtement, je ne voudrais pas créer/maintenir un plugin séparé juste au démarrage AMQ après le chargement d'hibernate. Je suis assuré qu'il y a un meilleur moyen. – Archer

+0

bien dans les plugins Grails sont composants. J'ai développé plusieurs plugins pour les applications juste parce que je pensais qu'ils auraient été mieux modularisés. Les plugins sont également un moyen utile d'intégrer des données ou des systèmes existants. Vous les gérez lorsque vous gérez l'application. Vous n'avez pas à les libérer dans la nature. – Sammyrulez

+0

Je l'ai;) Mais dans tous les cas - je ne déplacerais pas le fichier d'initialisation simple activemq.xml de l'application principale dans un autre 'component' avec la structure complète du projet plugin Grails, le publier sur svn et maintenir un autre groupe de sources retarder l'initialisation AMQ. Il y a un moyen plus simple. Le bean AMQ supporte la propriété 'start' qui indique si elle doit être autostarted ou non. Va l'utiliser comme pour le moment. – Archer

4

Si tous ceux-ci sont définis comme le haricot de printemps, vous pouvez utiliser

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

Cela fera en sorte anotherBean est initialisé avant activeMqBean

+0

Merci Bonzo, mais je sais déclaration 'depends-on'. Malheureusement, cela ne fonctionnera pas car l'initialisation de Grails est sur une autre couche que Spring. Il n'y a donc aucun bean sur lequel Activemq devrait dépendre. – Archer

3

Je ne suis pas sûr dans votre cas, mais chargement paresseux peut également aider, par exemple.

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

Un grain paresseux initialisé indique au conteneur IoC pour créer une instance de haricot lors de la première demande. Cela peut vous aider à retarder le chargement des haricots que vous voulez.

+0

Cela ne fonctionnera pas aussi, car mon bean DAO est à coup sûr demandé AVANT le chargement d'hibernate. – Archer

0

Je sais que cette question est assez ancienne, mais je suis maintenant confronté au même problème en l'an 2015 - et ce fil ne propose pas de solution pour moi.

Je suis venu avec un bean de processeur personnalisé ayant un CountDownLatch, que je compte après l'amorçage de l'application. Ainsi, les messages seront mis en attente jusqu'à ce que l'application a pleinement démarré et que cela fonctionne pour moi.

/** 
* 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() 
    } 
} 

ensuite l'utiliser comme un haricot dans votre application et appeler la méthode setBootstrapped dans votre Bootstrap.groovy

Ensuite, dans votre RouteBuilder vous mettez le processeur entre votre terminal et de destination pour tous les itinéraires que vous attendez des messages à venir avant l'application a commencé:

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