2012-06-08 15 views
5

Storicamente ho distribuito le mie applicazioni consumer JMS come applicazioni web di Spring distribuite sotto Tomcat (casella di Windows). Questi utenti verranno quindi visualizzati insieme alle altre mie applicazioni web sotto la stessa istanza di Tomcat. Tuttavia, dal momento che il numero di consumatori che utilizzo è cresciuto, mi sono reso conto che questo si sta trasformando in un incubo di manutenzione.JMS Utente autonomo con ActiveMQ e Spring

La mia soluzione era quella di convertire queste applicazioni web in app "main method" installate come jar. In effetti, sono riuscito a raggrupparli tutti insieme nel tentativo di riutilizzare il maggior numero possibile di risorse (DAO, dipendenze, ecc.).

Ecco ciò che il mio metodo principale si presenta come:

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); 
    } 
} 

La mia domanda (s):

  1. Ho bisogno di fare nulla di speciale per arrestare i miei collegamenti JMS nella mia applicazione metodo principale, o si spegneranno perfettamente mentre l'applicazione termina?
  2. Qualcuno ha qualche preferenza personale o altro riguardo se distribuire i consumatori jms utilizzando tomcat o come app standalone?

Edit:

Un po 'più di informazioni: FooListener e BarListener estendono la seguente classe astratta. Essi ereditano i loro valori dai bean corrispondenti nel file applicationContext.xml e entrambi sovrascrivono il metodo onMessage() per consumare in modo asincrono i messaggi.

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); 
} 

risposta

4

Devi registrarti un gancio di chiusura del contesto applicativo in questo modo:

context.registerShutdownHook(); 

Questo farà sì che quando la JVM viene arrestato, il contesto è chiuso anche con grazia.

mia preferenza personale è sempre quello di distribuirlo in un contenitore - anche le applicazioni standalone come questi, questo è a causa dei seguenti motivi:

  • L'amministrazione è più facile - la distribuzione/undeploying la guerra di applicazione, a partire/arresto del runtime del contenitore.
  • Se hai bisogno di costruire qualsiasi tipo di monitoraggio - quanti messaggi vengono consumati, questo sarà più facile con questa configurazione, puoi semplicemente aggiungere pagine web che presentano informazioni rilevanti o dire usando jmx con un'applicazione standalone.

Inoltre, perché si sta chiamando esplicitamente listener.start(), il contenitore Spring lo fa automaticamente in ogni caso?

+0

Questa è una domanda davvero buona - non avevo idea che il contenitore molla chiamasse automaticamente il metodo start() sull'ascoltatore. Mentre cercavo la documentazione su questo mi sono imbattuto in un blog su JmsTemplate, che potrebbe rendermi la vita più facile ... http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive- jms-messages.html –

+1

FYI - Sono stato in grado di rimuovere le chiamate manuali listener.start() aggiungendo init-method = "start" ai miei bean di spring:

+1

Oh, ok, ho capito il metodo di avvio.In realtà anche questo non è richiesto in quanto è possibile registrare il listener come delegato al MessageListenerContainer a cui si inietta la connectionFactory: ecco un buon riferimento - http://static.springsource.org/spring/docs/3.1.x/spring -framework-reference/html/jms.html # jms-mdp –

Problemi correlati