Spring整合Rabbitmq

RabbitMQ是流行的开源消息队列系统,用erlang语言开发。在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,需要用到RabbitMQ

没有找到一篇完整的文章介绍Spring如何整合Rabbitmq应用,琢磨一天搞出的一个入门的demo与伙伴们分享.

第一步linux环境下安装rabbitMQ,小弟用的是ubantu,不想浪费太多时间这种安装上

sudo apt-get install rabbitmq-server

默认启动端口5672 测试账户guest 密码guest

官方常用命令,想更改用户的可以参考,这里不作详细说明http://www.rabbitmq.com/man/rabbitmqctl.1.man.html

也可以省去安装115.28.141.137个人私服已配置好

第二步添加依赖包

?
1
2
3
4
5
6
7
8
9
10
11
<dependency>
             <groupId>org.springframework.amqp</groupId>
             <artifactId>spring-rabbit</artifactId>
             <version> 1.3 . 5 .RELEASE</version>
         </dependency>
     
         <dependency>
             <groupId>commons-lang</groupId>
             <artifactId>commons-lang</artifactId>
             <version> 2.6 </version>
         </dependency>

第三步配置生产者工程服务配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version= "1.0" encoding= "UTF-8" ?>
<beans xmlns= "http://www.springframework.org/schema/beans"
     xmlns:context= "http://www.springframework.org/schema/context"
     xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:task= "http://www.springframework.org/schema/task"
     xmlns:rabbit= "http://www.springframework.org/schema/rabbit"
     xsi:schemaLocation="http: //www.springframework.org/schema/beans
       http: //www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http: //www.springframework.org/schema/context
       http: //www.springframework.org/schema/context/spring-context.xsd
       http: //www.springframework.org/schema/integration/ip
       http: //www.springframework.org/schema/integration/ip/spring-integration-ip-2.0.xsd
       http: //www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
       http: //www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
       http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http: //www.springframework.org/schema/rabbit
       http: //www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
       ">
 
     <!-- 引入jdbc配置文件 -->
     <context:property-placeholder location= "classpath:conf/jdbc.properties" />
 
     <!-- 扫描文件(自动将servicec层注入) -->
     <context:component-scan base- package = "mq.service" />
     <!-- 连接服务配置 -->
     <rabbit:connection-factory id= "connectionFactory"
         host= "115.28.141.137" username= "guest" password= "guest" port= "5672" />
 
     <rabbit:admin connection-factory= "connectionFactory" />
 
     <!-- queue 队列声明 -->
     <rabbit:queue id= "queue_one" durable= "true" auto-delete= "false"
         exclusive= "false" name= "queue_one" />
 
 
     <!-- exchange queue binging key 绑定 -->
     <rabbit:direct-exchange name= "my-mq-exchange"
         durable= "true" auto-delete= "false" id= "my-mq-exchange" >
         <rabbit:bindings>
             <rabbit:binding queue= "queue_one" key= "queue_one_key" />
         </rabbit:bindings>
     </rabbit:direct-exchange>
 
     <!-- spring amqp默认的是jackson
     的一个插件,目的将生产者生产的数据转换为json存入消息队列,由于fastjson的速度快于jackson,这里替换为fastjson的一个实现
     -->
     <bean id= "jsonMessageConverter" class = "mq.util.FastJsonMessageConverter" ></bean>
 
     <!-- spring template声明-->
     <rabbit:template exchange= "my-mq-exchange" id= "amqpTemplate"
         connection-factory= "connectionFactory" message-converter= "jsonMessageConverter" />
</beans>

FastJsonMessageConverter 类代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package mq.util;
 
import java.io.UnsupportedEncodingException;
 
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.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.fastjson.JSON;
 
public class FastJsonMessageConverter  extends AbstractMessageConverter {
     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 ();
         //init();
     }
      
     public void setDefaultCharset(String defaultCharset) {
         this .defaultCharset = (defaultCharset != null ) ? defaultCharset
                 : DEFAULT_CHARSET;
     }
      
     public Object fromMessage(Message message)
             throws MessageConversionException {
         return null ;
     }
      
     @SuppressWarnings ( "unchecked" )
     public <T> T fromMessage(Message message,T t) {
         String json = "" ;
         try {
             json = new String(message.getBody(), "UTF-8" );
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
         }
         return (T) JSON.parseObject(json, t.getClass());
     }  
      
  
     protected Message createMessage(Object objectToConvert,
             MessageProperties messageProperties)
             throws MessageConversionException {
         byte [] bytes = null ;
         try {
             String jsonString = JSON.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);
  
     }
}

生产者代码Producer

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<p>
package mq.service;
</p>
 
<p>
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
  
@Service
public class ProducerMq {
      
     @Autowired
     private AmqpTemplate amqpTemplate;
      
     public void sendDataToCrQueue(Object obj) {
         amqpTemplate.convertAndSend( "queue_one_key" , obj);
     }  
}
</p>

 

第四步配置消费者服务工程配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?xml version= "1.0" encoding= "UTF-8" ?>
<beans xmlns= "http://www.springframework.org/schema/beans"
     xmlns:context= "http://www.springframework.org/schema/context"
     xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:task= "http://www.springframework.org/schema/task"
     xmlns:rabbit= "http://www.springframework.org/schema/rabbit"
     xsi:schemaLocation="http: //www.springframework.org/schema/beans
       http: //www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http: //www.springframework.org/schema/context
       http: //www.springframework.org/schema/context/spring-context.xsd
       http: //www.springframework.org/schema/integration/ip
       http: //www.springframework.org/schema/integration/ip/spring-integration-ip-2.0.xsd
       http: //www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
       http: //www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
       http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http: //www.springframework.org/schema/rabbit
       http: //www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
       ">
 
     <!-- 引入jdbc配置文件 -->
     <context:property-placeholder location= "classpath:conf/jdbc.properties" />
 
     <!-- 扫描文件(自动将servicec层注入) -->
     <context:component-scan base- package = "mq.service" />
     <task:executor id= "taskExecutor" pool-size= "1-4" queue-capacity= "128" /> 
      <!-- 连接服务配置  -->
    <rabbit:connection-factory id= "connectionFactory" host= "115.28.141.137" username= "guest"
         password= "guest" port= "5672"  />
          
    <rabbit:admin connection-factory= "connectionFactory" />
     
    <!-- queue 队列声明-->
    <rabbit:queue id= "queue_one" durable= "true" auto-delete= "false" exclusive= "false" name= "queue_one" />
     <!-- exchange queue binging key 绑定 -->
     <rabbit:direct-exchange name= "my-mq-exchange" durable= "true" auto-delete= "false" id= "my-mq-exchange" >
         <rabbit:bindings>
             <rabbit:binding queue= "queue_one" key= "queue_one_key" />
         </rabbit:bindings>
     </rabbit:direct-exchange>
     <bean id= "queueOneLitener" class = "mq.service.QueueOneLitener" />
         <!-- queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->
     <rabbit:listener-container connection-factory= "connectionFactory" acknowledge= "auto" task-executor= "taskExecutor" >
         <rabbit:listener queues= "queue_one" ref= "queueOneLitener" /> <span></span> </rabbit:listener-container>
</beans>

监听器代码queueOneLitener

?
1
2
3
4
5
6
7
8
9
10
11
package mq.service;
 
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
  
public class QueueOneLitener implements  MessageListener{
     public void onMessage(Message message) {
     
         System.out.println( " data :" + new String(message.getBody()));
     }
}

第五步测试

消费者端控制层生产数据

控制层Controller

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package mq.controller;
 
import javax.annotation.Resource;
 
import mq.service.ProducerMq;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class MessageController {
     @Resource
     private ProducerMq producer;
     @RequestMapping ( "/producer" )
     public String producer() throws Exception {
         for ( int i= 0 ;i< 100 ;i++){
             producer.sendDataToCrQueue( "data" +i);
         }
         return "index" ;
     }
 
 
}

运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值