在MQ消息服务框架方面, Spring官方提供了RabbitMQ的使用案例, 采用的是SpringBoot的方式(messaging-rabbitmq); 接下来, 我们采用Xml配置的方式结合RabbitMQ到SpringMvc里面玩玩!
环境: Win10+Jdk1.8+Spring4.3+RabbitMQ3.6.5
1 . 本地先安装RabbitMQ服务
请参考这里URL,下载合适自己的安装包并进行安装!因为Rabbit是基于Erlang平台运行的, 借用了它的并发性, 分布式等特性, 所以安装Erlang环境可以看URL! 为了后续方便, 可以在安装完RabbitMQ后配置下它的环境变量!
2 . 看下RabbitMQ的运行状态, 有需要的话可以再添加一下自己服务的配置, 在命令行执行以下命令
1> 查询RabbitMQ的状态
rabbitmqctl status
2> 查询系统用户列表, “guest” 默认密码也是”guest”, 它的角色是”administrator”, 系统最高权限者, 可以登陆后台管理系统, 查看系统的所有状态信息及相关增删操作!
rabbitmqctl list_users
3> 先执行下面的命令启用后台管理功能, 然后访问 “http://127.0.0.1:15672/“, 再使用超级管理员guest进行登陆查看并操作!
rabbitmq-plugins enable rabbitmq_management
4> 创建一个新用户!
rabbitmqctl add_user Username Password
5> 创建一个新虚拟主机目录, 相当于后续的消息收发的操作空间!
rabbitmqctl add_vhost vhost_name
6> 针对一个Vhost授权某个用户的操作权限!
rabbitmqctl set_permissions -p vhost_name guest ".*" ".*" ".*" (这句是授权超级管理员进行监控)
rabbitmqctl set_permissions -p /hisoka_host hisoka "^hisoka-.*" ".*" ".*"(这句授权给普通用户进行操作)
其中的["^hisoka-.*"]会同时限制到后面的exchange和[routingKey,queue]
2 . 进行Spring配置, 项目源码SSM
1> 引进maven依赖
<!-- ===================== rabbitMQ ================== -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
<!-- ===================== /rabbitMQ ================== -->
2> SpringMVC XML配置相关bean
<!-- Create Queue -->
<bean id="queue" class="org.springframework.amqp.core.Queue" >
<constructor-arg name="name" value="${mq.consumer.queue}" />
</bean>
<!-- The Exchange -->
<bean id="topicExchange" class="org.springframework.amqp.core.TopicExchange" >
<constructor-arg name="name" value="${mq.producer.exchange}" />
</bean>
<!-- Binding Proxy having Queue and exchange -->
<bean id="bindingProxy" class="com.hisoka.MQueue.rabbit.BindingProxy" >
<property name="queue" ref="queue" />
<property name="exchange" ref="topicExchange" />
</bean>
<!-- Binding the Exchange and Queue with routing.key -->
<bean id="binding" factory-bean="bindingProxy" factory-method="getBinding" ></bean>
<!-- message converter -->
<bean id="messageConverter" class="org.springframework.amqp.support.converter.SimpleMessageConverter" />
<!-- connection factory to connect RabbitMQ server-->
<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<constructor-arg index="0" value="${mq.server.host}" />
<constructor-arg index="1" value="${mq.server.port}" />
<property name="virtualHost" value="${mq.server.virtualhost}" />
<property name="username" value="${mq.username}" />
<property name="password" value="${mq.password}" />
</bean>
<bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin">
<constructor-arg ref="connectionFactory" />
</bean>
<!-- rabbit template to send message-->
<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageConverter" ref="messageConverter" />
<property name="exchange" value="${mq.producer.exchange}" />
<property name="routingKey" value="${mq.producer.routing.key}" />
</bean>
<!-- message listener adapter -->
<bean id="messageListenerAdapter" class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter" >
<constructor-arg name="delegate" ref="messageReceiver" />
</bean>
<!-- message listener adapter Container -->
<bean id="simpleMessageListenerContainer" class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer" >
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListener" ref="messageListenerAdapter" />
<property name="queueNames" value="${mq.consumer.queue}" />
</bean>
3> 涉及到基础类
/*进行exchange与queue的绑定, 当Rabbit上没有时就创建并绑定*/
package com.hisoka.MQueue.rabbit;
import org.springframework.amqp.core.*;
/**
* @author Hinsteny
* @date 2016/9/23
* @copyright: 2016 All rights reserved.
*/
public class BindingProxy {
private Queue queue;
private TopicExchange exchange;
public void setQueue(Queue queue) {
this.queue = queue;
}
public void setExchange(TopicExchange exchange) {
this.exchange = exchange;
}
public Binding getBinding(){
return BindingBuilder.bind(queue).to(exchange).with(queue.getName());
}
}
/*消息接收处理器*/
package org.hinsteny.service.impl.MQ;
import com.hisoka.MQueue.rabbit.MessageListenerProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author Hinsteny
* @date 2016/9/23
* @copyright: 2016 All rights reserved.
*/
@Component("messageReceiver")
public class MyMessageReceiver extends MessageListenerProxy{
private static final Logger logger = LoggerFactory.getLogger(MyMessageReceiver.class);
private volatile List<String> messages = new ArrayList(64);
public List<String> getMessages() {
List<String> result = new ArrayList(messages);
this.messages.clear();
return result;
}
@Override
public Object handleMessage(String messageId, String messageContent, String queue) {
if (logger.isInfoEnabled()) logger.info("Receive message id {}, queue {} and content is {}", messageId, queue, messageContent);
this.messages.add(messages.toString());
return true;
}
}
3 . Web Test
/*Web rest Action*/
@Get("/testMQ/send")
@ResponseBody
public WebResponse testSendMQ(HttpServletRequest request, @RequestParam(name = "name") String name, HttpServletResponse response) {
boolean result = mqService.sendMessage(name);
return WebResponse.success(result);
}
@Get("/testMQ/get")
@ResponseBody
public WebResponse testGetMQ(HttpServletRequest request, HttpServletResponse response) {
List<String> result = mqService.getMessage();
return WebResponse.success(result);
}
/*Service*/
package org.hinsteny.service.impl.MQ;
import org.hinsteny.service.MQService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Hinsteny
* @date 2016/9/22
* @copyright: 2016 All rights reserved.
*/
@Service
public class MQServiceImpl implements MQService{
@Autowired
MyMessageReceiver receiver;
@Autowired
RabbitTemplate rabbitTemplate;
@Override
public boolean sendMessage(String message) {
rabbitTemplate.convertAndSend(message);
return true;
}
@Override
public List<String> getMessage() {
return receiver.getMessages();
}
}