lunes, 24 de enero de 2011

ActiveMQ con Spring

Vamos a crear dos aplicaciones con spring y maven. Una para publicar mensajes asincronos en ActiveMQ y un cliente para leerlo. Creamos 2 proyecto para que sea notoria la separación de cliente-servidor.

Primero creemos los proyectos con maven:

mvn archetype:create -DgroupId=org.assembly -DartifactId=creadorDeMensajes

mvn archetype:create -DgroupId=org.assembly -DartifactId=lectorDeMensajes

Ahora editemos los pom's para utilizar spring:

pom.xml de creadorDeMensajes:




4.0.0

org.assembly

creadorDeMensajes

1.0-SNAPSHOT

jar

creadorDeMensajes

http://maven.apache.org


UTF-8





org.springframework
spring
2.5.6.SEC02



org.apache.activemq
activemq-all
5.4.2








pom.xml de LectorDeMensajes:




4.0.0

org.assembly

lectorDeMensajes

1.0-SNAPSHOT

jar

lectorDeMensajes

http://maven.apache.org


UTF-8





org.springframework
spring
2.5.6.SEC02



org.apache.activemq
activemq-all
5.4.2







Importante que borren los test porque no tenemos la dependencia con jUnit vayan a la carpeta:
creadorDeMensajes/src/test/java/org/assembly y lectorDeMensajes/src/test/java/org/assembly y borren AppTest.java

Corremos:
mvn clean install
mvn eclipse:eclipse

para los dos proyectos, es decir entramos en la carpeta: creadorDeMensajes y corremos los comandos y luego hacemos lo mismo para lectorDeMensajes. Lo cual nos bajara los jars necesarios.

Creador De Mensajes
Antes que nada es recomendable utilizar una ide yo estoy usando eclipse. Para importar los proyectos a eclipse vea el siguiente link:

Vamos a centrarnos en este proyecto, que va a crear los mensajes para luego ser leídos por el lector.
En el la carpeta creadorDeMensajes/src/main/resources (si no existe la crean) vamos a generar el archivo xml para configurar los beans que vamos a utilizar para enviar mensajes. Creamos el archivo spring-context.xml con el siguiente contenido:

























El primer bean que definimos es la fabrica de conecciones a ActiveMQ, como piedad definimos la URL del corredor de mensajes. EL segundo bean es el destino que como parametro se pasa un nombre de destino. El terser bean es el objeto Template que nos hace la vida más facil a la hora de programar con ActiveMQ es una clase de spring y se configura la fabrica de conección. El cuarto bean es nuestra clase que envia mensajes.

Necesitamos una interfaz que describa el servicio, la llamamos EnviadorDeMensajes.java :



package org.assembly;

/**
* @author emanuel
*
*/
public interface EnviadorDeMensajes {

void enviarUnMensaje();

}


Luego programamos la implementación EnviadorDeMensajesImpl.java:


package org.assembly;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

/**
* @author emanuel
*
*/
public class EnviadorDeMensajesImpl implements EnviadorDeMensajes {

private static final String MENSAJE = "Hoy te escribo una carta mi pequeña Maria, " +
"yo que tanto te quiero y que todos los días me acuerdo de ti, " +
"yo me acuerdo de ti.";

private JmsTemplate jmsTemplate = null;

// usado por spring para inyectar el jms template.
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}


private Destination destino = null;

// usado por spring para inyectar el destino.
public void setDestino(Destination destino) {
this.destino = destino;
}


/**
* @see org.assembly.EnviadorDeMensajes#enviarUnMensaje()
*/
@Override
public void enviarUnMensaje() {
jmsTemplate.send(
this.destino,
new MessageCreator() {

@Override
public Message createMessage(Session session) throws JMSException {
MapMessage mensaje = session.createMapMessage();

mensaje.setString("mensaje", MENSAJE);

return mensaje;
}
}
);
}

}


La Clase envía el mensaje gracias a JmsTemplate.

Y ahora programamos la aplicación llamada AppCreador.java :

package org.assembly;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;


public class AppCreador
{
public static void main( String[] args )
{
BeanFactory fabricaDeBeans = new XmlBeanFactory(new FileSystemResource("src/main/resources/spring-context.xml"));

EnviadorDeMensajes enviador = (EnviadorDeMensajes) fabricaDeBeans.getBean("miEnviadorDeMensajes");

enviador.enviarUnMensaje();
}
}

Utilizamos a spring como fabrica de beans y le pedimos que cree el enviador; luego con el enviamos un mensaje.

Para probar esto hay que subir activeMQ, para subirlo hay que hacer:
activemq console (en sistemas Unix-Like)
activemq (en Windows)
Luego podemos ejecutar el AppCreador.

Lector De Mensajes
El lector es similar al enviador, veamos el spring-context.xml:
























Ahora configuramos el destino como default en jmsTemplate para no pasarlo al lector y de esta forma es más ágil.
Necesitamos una interfaz para el lector:

package org.assembly;

import javax.jms.JMSException;

public interface LectorDeMensajes {

String leer() throws JMSException;

}



Y la implementación:


package org.assembly;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

/**
* @author emanuel
*
*/
public class LectorDeMensajesImpl implements LectorDeMensajes {

private JmsTemplate jmsTemplate = null;

// usado por spring para inyectar el jms template.
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}


/**
* @throws JMSException
* @see org.assembly.EnviadorDeMensajes#enviarUnMensaje()
*/
@Override
public String leer() throws JMSException {
MapMessage mensaje = (MapMessage) jmsTemplate.receive();
return mensaje.getString("mensaje");
}


}


Ahora creamos la aplicación lectora:

package org.assembly;

import javax.jms.JMSException;

import org.sprin
gframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

/**
* Hello world!
*
*/
public class AppLector
{
public static void main( String[] args ) throws JMSException
{
BeanFactory fabricaDeBeans = new XmlBeanFactory(new FileSystemResource("src/main/resources/spring-context.xml"));

LectorDeMensajes lectorDeMensajes = (LectorDeMensajes) fabricaDeBeans.getBean("miLectorDeMensajes");
System.out.println(lectorDeMensajes.leer());
}
}


Si ejecutamos esta aplicación devolvera el mensaje enviado por el creadorDeMensajes.
Este es un pequeño ejemplo del uso de Apache Active con spring espero que les sirva.