Voici un mode d’emploi simple pour mettre en oeuvre JMS en utilisant Spring. Bien entendu il vous faut pour cela au minimum un serveur JMS (serveur d’application, ou ActiveMQ ou encore OpenJMS). Comme vous allez le voir, le codage et la paramétrage sont assez simples en fait
Spring met à votre disposition 2 dispositifs rendant l’utilisation de JMS très simple :
- JmsTemplate : gère la connexion vers le serveur déclaré et l’envoi des données
- SimpleMessageListenerContainer : assure la réception des messages et l’appel à votre classe en charge de traiter la réception des objets.
1ère étape : déclaration du serveur
Dans un fichier xml de configuration Spring, insérez ces lignes (dans notre exemple, il s’agit de la déclaration des 2 serveurs ActiveMQ locaux) :
<!-- ActiveMQ Sender --> <bean id="connectionFactorySender" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean> <!-- ActiveMQ Receiver --> <bean id="connectionFactoryListener" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean>
ainsi que la déclaration de la queue qui sera utilisée pour nos échanges de messages :
<bean id="categs_backup_queue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="categs_backup"/> </bean>
2ème étape : gestion de l’émission des messages
Dans notre exemple, nous échangerons des POJOs représentants des catégories afin de les sauvegarder sur un autre serveur.
Voici l’implémentation de la classe servant à envoyer ces messages :
public class CategorieBackupSenderImpl implements CategorieBackupSender {
private JmsTemplate jmsTemplate;
private Queue queue;
@Required
public void setConnectionFactory(ConnectionFactory cf) {
this.jmsTemplate = new JmsTemplate(cf);
}
@Required
public void setQueue(Queue queue) {
this.queue = queue;
}
/* (non-Javadoc)
* @see com.bp.jms.CategorieBackupSender#simpleSend()
*/
public void send(final Categorie categ) {
this.jmsTemplate.send(this.queue, new MessageCreator() {
public ObjectMessage createMessage(Session session) throws JMSException {
return (ObjectMessage) session.createObjectMessage(categ);
}
});
}
}
Les deux setters servent à Spring pour renseigner les propriétés nécessaires au bon fonctionnement de cette classe : le template (JmsTemplate) qui utilise la connexion au serveur JMS (ConnectionFactory) et la queue (Queue).
La méthode Send fait appel au template pour créer le message à partir de notre POJO via la classe MessageCreator.
Il nous reste à déclarer ce composant dans le XML de configuration Spring :
<bean id="categorieBackupSender" class="com.bp.categories.jms.impl.CategorieBackupSenderImpl"> <property name="connectionFactory" ref="connectionFactorySender"/> <property name="queue" ref="categs_backup_queue"/> </bean>
C’est tout pour l’émission des messages ! La bonne nouvelle c’est que la réception n’est guère plus compliquée
3è étape : gestion de la réception des messages
Voici la classe gérant cette réception :
public class CategorieBackupListener implements MessageListener {
private CategorieService categorieService;
/**
* @param categorieService the categorieService to set
*/
@Required
public void setCategorieService(CategorieService categorieService) {
this.categorieService = categorieService;
}
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
try {
Categorie categ = (Categorie) ((ObjectMessage) message).getObject();
categorieService.backup(categ);
}
catch (JMSException ex) {
throw new RuntimeException(ex);
}
}
else {
throw new IllegalArgumentException("Message must be of type ObjectMessage");
}
}
}
Le source est assez parlant de lui-même. Suite à la réception du message, le service CategorieService est appelé afin d’effectuer le traitement approprié.
De même que pour l’émission, la configuration Spring est importante…
<bean id="categorieBackupListener" class="com.bp.categories.jms.CategorieBackupListener"> <property name="categorieService" ref="categorieService" /> </bean> <bean id="listener" class="org.springframework.jms.listener.SimpleMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactoryListener"/> <property name="destination" ref="categs_backup_queue"/> <property name="concurrentConsumers" value="3"/> <property name="messageListener" ref="categorieBackupListener"/> </bean>
Bien entendu dans cet exemple nous échangeons des POJOs reconnus par JMS comme simple Object. Il est possible d’améliorer tout ça, ne serait-ce que pour s’assurer que l’objet reçu est bien l’objet attendu ou aussi pour échanger des objets de différents types en utilisant la même queue.
4ème étape : fonctionnement de notre exemple
Nous devons déclarer nos deux beans :
categorieService = (CategorieService) Context.getContext().getBean("categorieService");
categorieBackupSender = (CategorieBackupSender) Context.getContext().getBean("categorieBackupSender");
puis la récupération de nos objets et leur envoi :
List<Categorie> categs = categorieService.getCategs();
if (categs != null) {
for (Categorie categ: categs) {
categorieBackupSender.send(categ);
}
}
La réception se met en route automatique dès l’instanciation du listener.
Si vous voulez contrôler le fonctionnement du listener, alors il faut déclarer un troisième bean :
listener = ((SimpleMessageListenerContainer) Context.getContext().getBean("listener"));
Voilà, cet exemple ne présente sans doute pas toutes les possibilités que l’on peut faire de JMS avec Spring, mais c’est un bon début



