在SpringBoot中使用RabbitMQ客户端详解

在SpringBoot中使用RabbitMQ客户端详解

前言

该示例使用的SpringBoot版本是2.2.2

添加依赖

引入amqp的依赖就行,AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。RabbitMQ就是对该协议的一种实现。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

编写配置

package com.example.demo.config;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Binding.DestinationType;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.amqp.core.Queue;

@Configuration
public class RabbitMQConfig implements InitializingBean {
	
	/**
	 * RabbitMQ的地址
	 */
	@Value("${rabbit.addresses}")
    private String addresses;

	/**
	 * RabbitMQ的登录名
	 */
    @Value("${rabbit.username}")
    private String username;

    /**
     * RabbitMQ的登录密码
     */
    @Value("${rabbit.password}")
    private String password;

    /**
     * 虚拟消息服务器
     */
    @Value("${rabbit.virtualhost}")
    private String virtualHost;
    
    @Value("${rabbit.queue1.name}")
    private String queue1Name;
    
    @Value("${rabbit.queue2.name}")
    private String queue2Name;
    
    @Value("${rabbit.exchange2.name}")
    private String exchange2Name;
    
    @Value("${rabbit.bindingKey2}")
    private String bindingKey2;
    
    /**
     * 通过这种方式可以申明一个队列,
     * 该队列使用跟队列名相同的bindingKey绑定了RabbitMQ默认的交换器
     * @return 队列
     */
    @Bean
    public Queue queue1() {
    	return new Queue(queue1Name);
    }
	
    /**
     * 创建连接工厂
     * @return 连接工厂
     */
	@Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        /*
	     	addresses的格式为192.168.7.82:5672,192.168.7.81:5672,多个地址之间用","隔开
	    	也可以用host和port来指定RabbitMQ地址
	    	cachingConnectionFactory.setHost("192.168.7.82");
	    	cachingConnectionFactory.setPort(5672);
         */
        cachingConnectionFactory.setAddresses(addresses);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        cachingConnectionFactory.setVirtualHost(virtualHost);

        return cachingConnectionFactory;
    }
	
	/**
	 * 配置消费者容器工厂
	 * @return 消费者容器工厂
	 */
	@Bean
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory listenerContainerFactory = new SimpleRabbitListenerContainerFactory();
        listenerContainerFactory.setConnectionFactory(connectionFactory());
        //手动ack
        listenerContainerFactory.setAcknowledgeMode(AcknowledgeMode.MANUAL);

        return listenerContainerFactory;
    }
	
	/**
    * RabbitMQ的template,通过该类可以收发消息
    * @return RabbitTemplate
    */
   @Bean
   public RabbitTemplate rabbitTemplate() {
	   return new RabbitTemplate(connectionFactory());
   }
   
   /**
   * 消息中间件的管理控制台。可以声明队列、交换器,以及绑定队列和交换器
   * @return AmqpAdmin
   */
  @Bean
  public AmqpAdmin amqpAdmin() {
      return new RabbitAdmin(connectionFactory());
  }

  @Override
  public void afterPropertiesSet() throws Exception {
	  AmqpAdmin amqpAdmin = amqpAdmin();
	  //声明一个队列
	  amqpAdmin.declareQueue(new Queue(queue2Name));
	  //声明一个交换器
	  amqpAdmin.declareExchange(new DirectExchange(exchange2Name));
	  //绑定交换器和队列
	  Binding binding = new Binding(queue2Name, DestinationType.QUEUE, exchange2Name, bindingKey2, null);
	  amqpAdmin.declareBinding(binding);
  }

}

application.yml

server:
  port: 8080
rabbit:
  addresses: 192.168.7.82:5672
  username: admin
  password: 123456
  virtualhost: /
  queue1:
    name: testQueue1
  exchange2:
    name: testExchange2
  queue2: 
    name: testQueue2
  bindingKey2: testBinding2
  queue3:
    name: testQueue3
  exchange3:
    name: testExchange3
  bindingKey3: testBinding3

编写生产者

package com.example.demo.mq;

import java.io.UnsupportedEncodingException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * RabbitMQ生产者
 * @author LiHao
 */
@Component
public class RabbitMQProducer {
	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	/**
	 * 发送字符串消息到默认的交换器
	 * @param routingKey 路由键(这里为了测试方便将路由键当做参数)
	 * @param msg 消息
	 */
	public void send(String routingKey, String msg) {
        this.rabbitTemplate.convertAndSend(routingKey, msg);
    }
	
	/**
	 * 发送字符串消息到指定的交换器
	 * @param exchange 交换器名称
	 * @param routingKey 路由键
	 * @param msg 消息
	 */
	public void send1(String exchange, String routingKey, String msg) {
        this.rabbitTemplate.convertAndSend(exchange, routingKey, msg);
    }

	/**
	 * 发送字节数组消息到指定交换器
	 * @param exchange 交换器名称
	 * @param routingKey 路由键
	 * @param msg 消息
	 * @throws UnsupportedEncodingException
	 */
    public void sendByte(String exchange, String routingKey, String msg) throws UnsupportedEncodingException {
        this.rabbitTemplate.convertAndSend(exchange, routingKey, msg.getBytes("utf-8"));
    }
}

编写消费者

package com.example.demo.mq;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;

/**
 * RabbitMQ消费者
 * @author LiHao
 *
 */
@Component
public class RabbitMQConsumer {
	
	/**
	 * 自动ack可以这样接收消息
	 * @param msg
	 */
	@RabbitListener(queues = "${rabbit.queue1.name}")
	@RabbitHandler
	public void receive1(String msg) {
		System.out.println("消费者从队列1接收到的消息:" + msg);
	}
	
	@RabbitListener(queues = "${rabbit.queue2.name}")
	@RabbitHandler
	public void receive2(String msg, Channel channel, Message message) {
		System.out.println("消费者从队列2接收到的消息:" + msg);
		long deliveryTag = message.getMessageProperties().getDeliveryTag();
		try {
			//确认收到消息,RabbitMQ将删除该消息
			channel.basicAck(deliveryTag, false);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	/**
	 * 使用@QueueBinding组合注解可以声明队列、交换器,并绑定队列和交换器
	 * @param msg
	 * @param channel
	 * @param message
	 */
	@RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value = "${rabbit.queue3.name}"),
                    exchange = @Exchange(value = "${rabbit.exchange3.name}"),
                    key = "${rabbit.bindingKey3}")
        })
    @RabbitHandler
	public void receive3(byte[] msg, Channel channel, Message message) {
		try {
			String str = new String(msg, "utf-8");
			System.out.println("消费者从队列3接收到的消息:" + str);
		} catch (UnsupportedEncodingException ex) {
			ex.printStackTrace();
		}
		
		long deliveryTag = message.getMessageProperties().getDeliveryTag();
		try {
			channel.basicAck(deliveryTag, false);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}

编写测试类

package com.example.demo.controller;

import java.io.UnsupportedEncodingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.mq.RabbitMQProducer;

@RestController
@RequestMapping("/test")
public class TestController {
	
	@Autowired
	private RabbitMQProducer rabbitMQProducer;
	
	@GetMapping("/mq/str")
	public String test(String exchange, String routingKey, String msg) {
		if (exchange != null) {
			rabbitMQProducer.send1(exchange, routingKey, msg);
		} else {
			rabbitMQProducer.send(routingKey, msg);
		}
		
		return "ok";
	}
	
	@GetMapping("/mq/byte")
	public String test1(String exchange, String msg, String routingKey) {
		try {
			rabbitMQProducer.sendByte(exchange, routingKey, msg);
		} catch (UnsupportedEncodingException ex) {
			ex.printStackTrace();
		}
		return "ok";
	}
}
发布了8 篇原创文章 · 获赞 15 · 访问量 956

猜你喜欢

转载自blog.csdn.net/qq_35939417/article/details/103922173