Статьи

Шаблон клиента Spring ActiveMQ Producer

Доступно на GitHub

Демо доступно на GitHub

обзор

Это очень маленький, очень простой шаблонный проект для отправки сообщений в очереди JMS.

В моей нынешней роли у нас есть много различных компонентов и систем, склеенных между собой ActiveMQ и Camel. При разработке \ интеграционном тестировании в этой среде часто полезно создавать специальные сообщения и отправлять их в очереди напрямую. Обычно это тот случай, когда вам нужно протестировать подмножество более крупной системы.

Обычно я запускаю тестовое приложение, часто повторяя эту функцию снова и снова. Поэтому я подумал, что было бы полезно вставить это в простой шаблонный проект, который можно легко использовать повторно. Также имеет смысл «mavenise» и «springify», чтобы сделать его более легко расширяемым, если вам нужно подключить другие компоненты и функции в тестах.

Просто повторюсь — это всего лишь отправная точка для стиля разработчика, специального тестирования для поддержки процесса разработки.

Запуск демо

  1. Предпосылки
    1. Запуск экземпляра ActiveMQ (локальный / удаленный)
    2. Maven и JDK установлены
  2. Настройка
    1. Отредактируйте свойства application.properties, чтобы они указывали на ваш экземпляр ActiveMQ, указав URL-адрес брокера и имя очереди.
    2. Отредактируйте файл «StartDemo.java», чтобы обеспечить ObjectMessage, ожидаемое конечной точкой
    3. Введите «maven exec: java», чтобы запустить класс StartDemo

application.properties

broker.url=tcp://localhost:61616
broker.queue=MyTestQueue

Глядя на код

Вся конфигурация Spring настраивается в основном application-context.xml

Приложение-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- Process Spring Annotations -->
	<context:component-scan base-package="com.cor.demo" />

	<bean id="serverProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>		
		<property name="placeholderPrefix" value="${applicationProperties."/>
		<property name="locations">
	    	<list>
	    		<value>classpath:/application.properties</value>
	    	</list>
	    </property>
		<property name="ignoreResourceNotFound" value="true"/>
	</bean>

	<!-- A JMS connection factory for ActiveMQ -->
	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
		p:brokerURL="${applicationProperties.broker.url}" />


	<!-- A destination in ActiveMQ -->
	<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="${applicationProperties.broker.queue}" /> 
	</bean>

	<!-- A cached connection to wrap the ActiveMQ connection -->
	<bean id="cachedConnectionFactory"
		class="org.springframework.jms.connection.CachingConnectionFactory"
		p:targetConnectionFactory-ref="connectionFactory" p:sessionCacheSize="10" />

	<!-- A JmsTemplate instance that uses the cached connection and destination -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
		p:connectionFactory-ref="cachedConnectionFactory"
		p:defaultDestination-ref="destination" />

</beans>

ObjectMessages создаются в основном классе StartDemo.java

StartDemo.java

package com.cor.demo.jms;

import java.io.Serializable;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.cor.demo.jms.dispatcher.MessageDispatcher;

/**
* Just a very simple template demo that will send a single Object Message to the JMS Broker and
* Queue name defined in application.properties file. This is just for simple throwaway testing
* purposes - designed as a starting point to develop on a case by case basis.
*/
public class StartDemo {

    /**
* @param args
*/
    public static void main(String[] args) {

        // Load spring config
        ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "application-context.xml" });
        BeanFactory factory = (BeanFactory) appContext;

        // Send Message
        MessageDispatcher dispatcher = (MessageDispatcher) factory.getBean("messageDispatcher");
        dispatcher.sendMessageObject(getTestMessage());
    }

    /**
* Generates the test message - overwrite with your own message.
* @return The object message to be sent to the JMS Queue
*/
    private static Serializable getTestMessage() {

        return "MY TEST MESSAGE";
    }
}

Связь с сервером абстрагируется в объект Dispatcher.

MessageDispatcher.java

package com.cor.demo.jms.dispatcher;

import java.io.Serializable;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;

/**
 * Simple JMS Client - configured in activemq-client-context.xml.
 * @author adrian.milne
 *
 */
@Component
public class MessageDispatcher {

    /** Logger. */
    private static Logger LOG = LoggerFactory.getLogger(MessageDispatcher.class);
    
    /** JMS Template. */
    @Autowired
    protected JmsTemplate jmsTemplate;

    /**
     * Send the objectMessage to the Broker and Queue defined in application.properties.
     * @param objectMessage Object Message
     */
    public void sendMessageObject(final Serializable objectMessage) {
        
        LOG.info("Sending message " + objectMessage);
        
        jmsTemplate.send(new MessageCreator() {

            public Message createMessage(Session session) throws JMSException {
                ObjectMessage message = session.createObjectMessage(objectMessage);
                return message;
            }
        });
        
        LOG.info("Message Sent!"); 

    }

}

И это действительно так!

Вывод 

Как указывалось в начале — это простой проект, который я использую в качестве отправной точки, когда мне нужно написать что-то для отправки сообщений в очередь ActiveMQ.

Это компромисс между чем-то очень простым (например, простым классом) и чем-то, что дает Сам легко расширяется. То, что часто начинается с простого теста, может перерасти во что-то более сложное — и, поскольку мы настроили maven и spring с самого начала — тогда очень легко добавить дополнительные зависимости, если вы обнаружите, что они вам нужны.