2010-08-11 40 views
7

Tiene una aplicación de primavera (en realidad la aplicación Grails) que ejecuta el servidor apache-activemq como Spring Bean y un par de rutas apache-camel. Uso de la aplicación Hibernate para trabajar con la base de datos. El problema es simple Activemq + Camel inicia BEFORE grails inyecta métodos especiales en hibernar objetos de dominio (en realidad, guardar/actualizar métodos, etc.). Por lo tanto, si activemq ya tiene algunos datos al inicio, camel inicia el procesamiento de los mensajes sin que se hayan inyectado los métodos DAO de grails. Esto falla con grails.lang.MissingMethodException. Debe retrasar el inicio de activemq/camel antes de que Grails inyecte métodos especiales en objetos de dominio.Cómo retrasar el arranque de frijoles primavera?

Respuesta

4

se puede mover managment MQ en un plugin? Aumentaría la modularidad y si declara en plugin-descriptor

def loadAfter = ['hibernate'] 

debe tener el comportamiento deseado. Funciona para JBPM plugin

+0

Bueno, honestamente, yo NO crearía/mantendría un plugin separado solo para iniciar AMQ después de que se haya cargado la hibernación. Estoy seguro de que hay una mejor manera. – Archer

+0

bien en los complementos de grails son componentes. He desarrollado varios complementos para aplicaciones solo porque pensé que habrían sido mejor modularizados. Los complementos también son una forma útil de integrar datos o sistemas heredados. Usted los mantiene mientras mantiene la aplicación. No tienes que liberarlos en la naturaleza. – Sammyrulez

+0

Lo tengo;) Pero en cualquier caso, NO movería un solo archivo de inicialización de ActiveMQ.xml de la aplicación principal a otro 'componente' con la estructura completa del proyecto de plugins de GRASS, lo publicaría en svn y mantendría otro grupo de fuentes solo para retrasar la inicialización de AMQ. Hay una manera más simple. La propiedad 'start' de soporte de beans de AMQ que indica si debe iniciarse automáticamente o no. Lo usaré como por ahora. – Archer

4

Si todos estos se definen como grano de primavera, se puede utilizar

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

Esto se asegurará de anotherBean se inicializa antes activeMqBean

+0

Gracias Bonzo, pero sé la declaración 'depends-on'. Desafortunadamente no funcionará ya que la inicialización de Grails está en una capa diferente luego de Spring. Así que simplemente no hay beans de los que activemq debería depender. – Archer

3

No estoy seguro en su caso, pero la carga diferida también puede ayudar, p.

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

Un grano inicializado perezosamente-indica al contenedor IoC para crear instancia del bean cuando se solicita primero. Esto puede ayudarlo a retrasar la carga de los granos que desee.

+0

Esto no funcionará también, ya que mi bean DAO se solicita con seguridad ANTES de que se cargue la hibernación. – Archer

0

Sé que esta pregunta es bastante antigua, pero ahora estoy enfrentando el mismo problema en el año 2015, y este hilo no ofrece una solución para mí.

Inventé un procesador personalizado que tiene un CountDownLatch, que cuento después de la inicialización de la aplicación. Entonces, los mensajes estarán inactivos hasta que la aplicación haya comenzado completamente y esté funcionando para mí.

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

luego usarlo como un grano en su aplicación y llame al método setBootstrapped en su Bootstrap.groovy

Luego, en su RouteBuilder se pone el procesador entre su punto final y de destino para todas las rutas que se pueden esperar los mensajes procedentes antes de que la aplicación haya comenzado:

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