1.ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线,实现了JMS(Java MessageService,实际上是指JMS API)可用来实现基于消息的RPC(过程远程调用)
对于Spring和Java程序员来说不一定要实现JMS,还有另外一种可选方案—AMQP(advanced message queuing protocol),即高级队列消息协议
下面将介绍的是ActiveMQ使用方法
2.下载地址:http://http://activemq.apache.org/点击打开链接
.解压目录:
4.添加Maven依赖
<span style="font-size:18px;"> <dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.13.3</version>
</dependency></span>
5.Spring配置
C命名空间:
xmlns:c="http://www.springframework.org/schema/c"
P命名空间:
<span style="font-size:18px;">xmlns:p="http://www.springframework.org/schema/p"</span>
Spring文件:
<!--声明连接工厂-->
<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"
p:brokerURL="tcp://${activeMq.destination.adderss}:${activeMq.destination.port}"
p:trustAllPackages="true"
/>
<!--<amd:connectionFactory id="connectionFactory" brokerURL="tcp://localhost:61616"/>-->
<!--声明消息目的地 队列形式 topic主题-->
<amd:queue id="queue" physicalName="access.control.msg"/>
<!--信息转换器-->
<bean id="messageConverter" class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
<!--JMS模板-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
c:_0-ref="connectionFactory"
p:defaultDestination-ref="queue"
p:messageConverter-ref="messageConverter"
/>
<!--发送信息-->
<bean id="sendActiveMqImpl" class="cn.com.reformer.communication.jmshandler.SendActiveMqImpl"/>
<!--处理信息-->
<bean id="activeMqHandler" class="cn.com.reformer.communication.jmshandler.ActiveMqHandler"/>
<!--监听器容器,实现POJO消息驱动,异步处理数据-->
<bean id="listenerContainer"
class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<!-- 消息监听器输出消息的数量 -->
<property name="concurrentConsumers" value="1"/>
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destinationName" value="access.control.msg"/>
<property name="messageListener" ref="activeMqHandler"/>
<property name="pubSubNoLocal" value="false"></property>
</bean>
ps:消息监听器容器还可以以jmsTemplate来实现,如下:
以这种方式配置的时候,消费者的数量会加倍,例concurrency="1"时,消费者数量为2 ,以上面的方式配置监听器容器时,将concurrentConsumers值设置为1真正实现单线程处理
<span style="font-size:18px;"> <!--监听器容器--> <!--acknowledge属性为"transacted",以开启事务 concurrency:多线程-->
<!-- <jms:listener-container connection-factory="connectionFactory" concurrency="1">
<jms:listener destination="</span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 18px;">access.control.msg</span><span style="font-family: Arial, Helvetica, sans-serif;">"</span><span style="font-size:18px;">
ref="</span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 18px;">messageHandler</span><span style="font-size:18px;">" method="handleMsg"/>
</jms:listener-container>--></span>
6.消息发送
public interface SendActiveMq {
void sendMessage(EntranceGuardUploadRecord message);
}
public class SendActiveMqImpl implements SendActiveMq {
private final static Logger LOGGER = Logger.getLogger(SendActiveMqImpl.class);
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private IEntranceGuardUploadRecordHandler uploadRecordHandler;
@Override
public void sendMessage(EntranceGuardUploadRecord message) {
jmsTemplate.convertAndSend(message);
LOGGER.error("######### jmsTemplate send queue message");
}
}
EntranceGuardUploadRecord为自定义POJO,必须实现Serializable接口
7.从ActiveMq服务接收消息,必须实现MessageListener接口,当有消息时自动调用onMessage方法
public class ActiveMqHandler implements MessageListener {
private static final Logger LOG = LoggerFactory.getLogger(ActiveMqHandler.class);
@Autowired
private JmsOperations jmsTemplate;
@Autowired
private IEntranceGuardUploadRecordHandler uploadRecordHandler;
@Override
public void onMessage(Message message) {
LOG.debug("######## consumer start handle msg");
EntranceGuardUploadRecord record = null;
if (message instanceof ObjectMessage) {
ObjectMessage objectMessage = (ObjectMessage) message;
try {
record = (EntranceGuardUploadRecord) objectMessage.getObject();
} catch (Exception e) {
e.printStackTrace();
LOG.error("acivemq convert message failure");
return;
}
}
}
以jms:listener-container标签配置监听器容器时可用
jmsTemplate来接收消息
Card card =(Card)jmsTemplate.receiveAndConvert();