springmvc+rabbitmq实例

在主框架为springmvc的项目中使用rabbitmq队列工具的配置和简单使用方法如下:

1、引入必须的4个jar包:

amqp-client-3.3.4.jar
spring-amqp-1.3.6.RELEASE.jar
spring-rabbit-1.3.6.RELEASE.jar
spring-retry-1.1.0.RELEASE.jar
2、在项目中添加amqp的配置文件,我再此命名为:spring-amqp.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:context="http://www.springframework.org/schema/context"
	xmlns:rabbit="http://www.springframework.org/schema/rabbit"
	xsi:schemaLocation="
            http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/rabbit
                http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

	<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">          
	    <!-- 核心线程数,默认为1 -->          
	    <property name="corePoolSize" value="10" />          
	    <!-- 最大线程数,默认为Integer.MAX_VALUE -->          
	    <property name="maxPoolSize" value="50" />          
	    <!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE -->          
	    <property name="queueCapacity" value="1000" />          
	    <!-- 线程池维护线程所允许的空闲时间,默认为60s -->          
	    <property name="keepAliveSeconds" value="300" />          
	    <!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->          
	    <property name="rejectedExecutionHandler">          
	        <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->          
	        <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 -->          
	        <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->          
	        <!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->          
	        <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />          
	    </property>          
	</bean>

	<!-- 连接服务配置  -->
    <rabbit:connection-factory id="connectionFactory" host="127.0.0.1" username="test"
        password="test" port="4567"  />

	<rabbit:admin connection-factory="connectionFactory" />

	<!-- queue 队列声明 需要发送消息到哪些队列-->
	<!-- 消息系统监听队列 -->
	<rabbit:queue id="message_queue" durable="true" auto-delete="false" exclusive="false" name="message_queue"/>
    
    <!-- exchange queue binging key 绑定 -->
    <rabbit:topic-exchange name="message-exchange" durable="true" auto-delete="false" id="message-exchange">
		<rabbit:bindings>
			<rabbit:binding queue="message_queue" pattern="message.*" />
		</rabbit:bindings>
	</rabbit:topic-exchange>

    <!-- spring amqp默认的是jackson 的一个插件,目的将生产者生产的数据转换为json存入消息队列,由于fastjson的速度快于jackson,这里替换为fastjson的一个实现 -->
    <bean id="jsonMessageConverter"  class="com.tonson.rabbitmq.message.FastJsonMessageConverter"></bean>
     
    <!-- spring template声明-->
    <rabbit:template exchange="message-exchange" id="amqpTemplate"  connection-factory="connectionFactory"  message-converter="jsonMessageConverter"/>
	
	<!-- 默认消息处理类,可以重写 -->
	<bean id="messageHandler" class="com.tonson.rabbitmq.MessageHandler"></bean>
	
	<!-- 用于消息的监听的代理类MessageListenerAdapter -->  
    <bean id="messageQueueListenerAdapter"  
        class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter">  
        <constructor-arg ref="messageHandler" />  
        <property name="defaultListenerMethod" value="handleMessage"></property>  
        <property name="messageConverter" ref="jsonMessageConverter"></property>  
    </bean> 
	
	<!-- 监听容器 -->
	<rabbit:listener-container
		connection-factory="connectionFactory" acknowledge="auto"
		task-executor="taskExecutor">
		<rabbit:listener queues="message_queue" ref="messageQueueListenerAdapter" />
	</rabbit:listener-container>
        <bean id="messageSender"  
                class="com.tonson.rabbitmq.service.MessageSender">  
                <property name="amqpTemplate" ref="amqpTemplate"></property>  
        </bean>
 </beans>
3、配置文件里提到的自定义的converter的内容如下:

package com.tonson.rabbitmq.message;

import java.io.UnsupportedEncodingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;

import com.alibaba.fastjson.JSONObject;

public class FastJsonMessageConverter extends AbstractMessageConverter {

	@SuppressWarnings("unused")
	private static Log log = LogFactory.getLog(FastJsonMessageConverter.class);

	public static final String DEFAULT_CHARSET = "UTF-8";

	private volatile String defaultCharset = DEFAULT_CHARSET;

	public FastJsonMessageConverter() {
		super();
	}

	public void setDefaultCharset(String defaultCharset) {
		this.defaultCharset = (defaultCharset != null) ? defaultCharset
				: DEFAULT_CHARSET;
	}

	public Object fromMessage(Message message)
			throws MessageConversionException {
		Object o = new CommonMessage();
		try{
			o = fromMessage(message, new CommonMessage());
		}catch(Exception e){
			log.error("queue message error : " + message);
			e.printStackTrace();
		}
		return o;
	}

	@SuppressWarnings("unchecked")
	public <T> T fromMessage(Message message, T t) {
		String json = "";
		try {
			json = new String(message.getBody(), defaultCharset);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return (T) JSONObject.parseObject(json, t.getClass());
	}

	protected Message createMessage(Object objectToConvert,
			MessageProperties messageProperties)
			throws MessageConversionException {
		byte[] bytes = null;
		try {
			String jsonString = JSONObject.toJSONString(objectToConvert);
			bytes = jsonString.getBytes(this.defaultCharset);
		} catch (UnsupportedEncodingException e) {
			throw new MessageConversionException(
					"Failed to convert Message content", e);
		}
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
		messageProperties.setContentEncoding(this.defaultCharset);
		if (bytes != null) {
			messageProperties.setContentLength(bytes.length);
		}
		return new Message(bytes, messageProperties);

	}
}
4、消息处理类MessageHandler.java的内容如下:

package com.tonson.message.rabbitmq;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.ClientProtocolException;

import com.alibaba.fastjson.JSONObject;

public class MessageHandler {

	private Log log = LogFactory.getLog(getClass());
	
	@Override
	public void handleMessage(CommonMessage message) {
		try{
			System.out.println("...." + message);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
}
5、发消息的类MessageSender.java内容如下:

package com.tonson.rabbitmq.service;

import org.springframework.amqp.core.AmqpTemplate;

public class MessageSender {
	
	private AmqpTemplate amqpTemplate;
	
	private String routingKey;

	public AmqpTemplate getAmqpTemplate() {
		return amqpTemplate;
	}

	public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
		this.amqpTemplate = amqpTemplate;
	}

	public String getRoutingKey() {
		return routingKey;
	}

	public void setRoutingKey(String routingKey) {
		this.routingKey = routingKey;
	}

	public void sendDataToQueue(Object obj) {
		amqpTemplate.convertAndSend(this.routingKey, obj);
	}
	
}
6、消息模型类如下:

package com.tonson.rabbitmq.message;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * 消息模型
 *
 */
public class CommonMessage {
	/**
	 * 约定的几个消息源名称
	 */
	private String source;
	/**
	 * 实体表名
	 */
	private String table;
	/**
	 * 主键
	 */
	private String primaryKey;
	/**
	 * 消息实体bean
	 */
	private Object message;

	public String getSource() {
		return source;
	}

	public void setSource(String source) {
		this.source = source;
	}

	public String getTable() {
		return table;
	}

	public void setTable(String table) {
		this.table = table;
	}


	public String getPrimaryKey() {
		return primaryKey;
	}

	public void setPrimaryKey(String primaryKey) {
		this.primaryKey = primaryKey;
	}

	public Object getMessage() {
		return message;
	}

	public void setMessage(Object message) {
		this.message = message;
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.DEFAULT_STYLE);
	}
	
}

到此为止,所有的配置都已经完成,然后就是发消息。

测试类如下所示:

package com.tonson.rabbitmq.demo;

import com.alibaba.fastjson.JSONObject;
import com.tonson.rabbitmq.message.CommonMessage;
import com.tonson.rabbitmq.service.MessageSender;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-amqp.xml")
public class RabbitMQDemo {

	@Resource
	private MessageSender messageSender;
	
	@Test
	public void testSendMessage(){
		CommonMessage message = new CommonMessage();
		message.setSource("tonson");
		JSONObject obj = new JSONObject();
		obj.put("test", "test json message");
		message.setMessage(obj);
		messageSender.setRoutingKey("message.tonson");
		messageSender.sendDataToQueue(message);
	}
	
}


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值