2012-06-08 17 views
5

Históricamente he implementado mis aplicaciones de consumo JMS como Spring webapps implementadas en Tomcat (Windows box). Estos consumidores se ejecutarán junto con mis otras aplicaciones web bajo la misma instancia de Tomcat. A medida que el número de consumidores que uso ha crecido, sin embargo, me he dado cuenta de que esto se está convirtiendo en una pesadilla de mantenimiento.JMS Consumidor autónomo con ActiveMQ y Spring

Mi solución fue convertir estos webapps a aplicaciones independientes de "método principal" implementadas como frascos. De hecho, pude empaquetarlos con éxito todos juntos en un intento de reutilizar tantos recursos (DAO, dependencias, etc.) como sea posible.

Esto es lo que mi método principal se parece a:

public static void main(String[] args) { 

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 

    try { 
     FooListener fooListener = (FooListener) context.getBean("fooListener"); 

     fooListener.start(); 
    } catch (Exception e) { 
     logger.error(e.getMessage(), e); 
    } 

    try { 
     BarListener barListener = (BarListener) context.getBean("barListener"); 

     barListener.start(); 
    } catch (Exception e) { 
     logger.error(e.getMessage(), e); 
    } 
} 

Mi pregunta (s):

  1. ¿Es necesario hacer nada especial para apagar mis conexiones JMS en mi aplicación principal método, ¿o se cerrarán bien cuando finalice la aplicación?
  2. ¿Alguien tiene alguna preferencia personal o de otro tipo sobre si implementar consumidores de jms utilizando Tomcat o como aplicaciones independientes?

edición: información

Un poco más: FooListener y BarListener extienden la siguiente clase abstracta. Heredan sus valores de los beans correspondientes en el archivo applicationContext.xml, y ambos anulan el método onMessage() para consumir mensajes asincrónicamente.

public abstract class TextMessageListener implements MessageListener { 

    protected ConnectionFactory connectionFactory; 

    protected String queueName; 

    protected String selectors; 

    public void start() throws JMSException { 
     Connection connection = connectionFactory.createConnection(); 

     Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); 

     MessageConsumer consumer = session.createConsumer(session.createQueue(queueName), selectors); 

     consumer.setMessageListener(this); 

     connection.start(); 
    } 

    public abstract void onMessage(Message message); 
} 

Respuesta

4

hay que registrarse un gancho de conclusión de su contexto de aplicación de esta manera:

context.registerShutdownHook(); 

Esto asegurará que cuando la JVM está apagado, el contexto también se cierra con gracia.

Mi preferencia personal es siempre para desplegarlo en un contenedor - incluso aplicaciones independientes como estos, esto se debe a las siguientes razones:

  • La administración es más fácil - el despliegue/anulación de la implementación de la guerra aplicación, a partir/detener el tiempo de ejecución del contenedor.
  • Si necesita construir cualquier tipo de monitorización: cuántos mensajes se están consumiendo, con esta configuración será más fácil, puede agregar páginas web que presenten información relevante frente a usar jmx con una aplicación independiente.

Además, ¿por qué llama explícitamente a listener.start(), el contenedor Spring lo hace automáticamente de todos modos?

+0

Esa es una muy buena pregunta, no tenía idea de que el contenedor de resorte llamaba automáticamente al método de inicio() en el oyente. Mientras buscaba la documentación sobre esto, me topé con un blog en JmsTemplate, que me puede hacer la vida más fácil ... http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive- jms-messages.html –

+1

FYI - Pude eliminar las llamadas manuales listener() añadiendo init-method = "start" a mis beans de primavera:

+1

Bueno, entiendo tu punto sobre el método de inicio.En realidad, incluso esto no es necesario, ya que puede registrar su oyente como un delegado en el MessageListenerContainer al que inyecta connectionFactory: aquí hay una buena referencia - http://static.springsource.org/spring/docs/3.1.x/spring -framework-reference/html/jms.html # jms-mdp –

Cuestiones relacionadas