springboot实现rabbitmq

最近学习springboot,想给项目添加rabbitmq进行实现,所以按照spring xml之前的文件重新配置了一边,毕竟springboot提倡代码优于配置。安装好rabbitmq后访问http://localhost:15672 用默认的账户:guest和密码:guest即可以登录

1.本次测试结构图

属性文件application.propterties配置如下

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.virtual-host=/
maven添加如下依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
添加主要配置文件

import com.fumubang.rabbitmq.callback.MsgSendConfirmCallBack;
import com.fumubang.rabbitmq.consumer.MessageConsumer;
import com.fumubang.rabbitmq.consumer.MessageConsumer2;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * <dl>
 * <dt>ConnectionFactory</dt>
 * <dd>Description:</dd>
 * <dd>CreateDate: 2017/8/31</dd>
 * </dl>
 *
 * @author Administrator
 */
@Configuration
public class ConnectionFactoryConfigure {

    @Value("${spring.rabbitmq.host}")
    public String host;
    @Value("${spring.rabbitmq.port}")
    public int port;
    @Value("${spring.rabbitmq.username}")
    public String username;
    @Value("${spring.rabbitmq.password}")
    public String password;
    @Value("${spring.rabbitmq.virtual-host}")
    public String virtualHost;

    /** 消息交换机的名字*/
    public static final String EXCHANGE = "exchangeTest";
    /** 队列key1*/
    public static final String ROUTINGKEY1 = "queue_one_key1";
    /** 队列key2*/
    public static final String ROUTINGKEY2 = "queue_one_key2";

    /**
        创建连接工厂
    * @date:2017/8/31
    * @className:ConnectionFactory
    * @author:Administrator
    * @description:
    */
    @Bean
    public CachingConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(this.host, this.port);
        connectionFactory.setUsername(this.username);
        connectionFactory.setPassword(this.password);
        connectionFactory.setVirtualHost(this.virtualHost);
        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

    /**
     1.定义direct exchange,绑定queueTest
     2.durable="true" rabbitmq重启的时候不需要创建新的交换机
     3.direct交换器相对来说比较简单,匹配规则为:如果路由键匹配,消息就被投送到相关的队列
     fanout交换器中没有路由键的概念,他会把消息发送到所有绑定在此交换器上面的队列中。
     topic交换器你采用模糊匹配路由键的原则进行转发消息到队列中
     key: queue在该direct-exchange中的key值,当消息发送给direct-exchange中指定key为设置值时,消息将会转发给queue参数指定
     的消息队列
     * @date:2017/9/1
     * @className:ConnectionFactory
     * @author:Administrator
     * @description:
     */
    @Bean
    public DirectExchange directExchange(){
        DirectExchange directExchange = new DirectExchange(ConnectionFactoryConfigure.EXCHANGE,true,false);
        return directExchange;
    }



    //--------------------定义queue_one------------------------------------------------
    @Bean
    public Queue queue_one(){
        /**
         *   durable="true" 持久化 rabbitmq重启的时候不需要创建新的队列
             auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
             exclusive  表示该消息队列是否只在当前connection生效,默认是false*/
        Queue queue = new Queue("queue_one",true,false,false);
        return queue;
    }

    /**
     将消息队列1和交换机进行绑定
     * @date:2017/9/1
     * @className:ConnectionFactoryConfigure
     * @author:Administrator
     * @description:
     */
    @Bean
    public Binding binding_one() {
        return BindingBuilder.bind(queue_one()).to(directExchange()).with(ConnectionFactoryConfigure.ROUTINGKEY1);
    }

    //--------------------定义queue_one------------------------------------------------

    //--------------------定义queue_two------------------------------------------------
    @Bean
    public Queue queue_two(){
        /**
         *   durable="true" 持久化 rabbitmq重启的时候不需要创建新的队列
         auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
         exclusive  表示该消息队列是否只在当前connection生效,默认是false*/
        Queue queue = new Queue("queue_two",true,false,false);
        return queue;
    }

    /**
     将消息队列2和交换机进行绑定
     * @date:2017/9/1
     * @className:ConnectionFactoryConfigure
     * @author:Administrator
     * @description:
     */
    @Bean
    public Binding binding_two() {
        return BindingBuilder.bind(queue_two()).to(directExchange()).with(ConnectionFactoryConfigure.ROUTINGKEY2);
    }

    //--------------------定义queue_two------------------------------------------------


    /**
     queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象
     * @date:2017/9/1
     * @className:ConnectionFactory
     * @author:Administrator
     * @description:
     */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer_one(){
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory());
        simpleMessageListenerContainer.addQueues(queue_one());
        simpleMessageListenerContainer.setExposeListenerChannel(true);
        simpleMessageListenerContainer.setMaxConcurrentConsumers(1);
        simpleMessageListenerContainer.setConcurrentConsumers(1);
        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        simpleMessageListenerContainer.setMessageListener(messageConsumer());
        return simpleMessageListenerContainer;
    }

    /**
     定义消费者
     * @date:2017/9/1
     * @className:ConnectionFactory
     * @author:Administrator
     * @description:
     */
    @Bean
    public MessageConsumer messageConsumer(){
        return new MessageConsumer();
    }

    /**
     queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象
     * @date:2017/9/1
     * @className:ConnectionFactory
     * @author:Administrator
     * @description:
     */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer_two(){
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory());
        simpleMessageListenerContainer.addQueues(queue_two());
        simpleMessageListenerContainer.setExposeListenerChannel(true);
        simpleMessageListenerContainer.setMaxConcurrentConsumers(1);
        simpleMessageListenerContainer.setConcurrentConsumers(1);
        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
        simpleMessageListenerContainer.setMessageListener(messageConsumer2());
        return simpleMessageListenerContainer;
    }

    /**
    定义消费者
     * @date:2017/9/1
            * @className:ConnectionFactory
     * @author:Administrator
     * @description:
    */
    @Bean
    public MessageConsumer2 messageConsumer2(){
        return new MessageConsumer2();
    }

    /**
    定义rabbit template用于数据的接收和发送
     * @date:2017/8/31
            * @className:ConnectionFactory
     * @author:Administrator
     * @description:*/
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        /**若使用confirm-callback或return-callback,必须要配置publisherConfirms或publisherReturns为true
         * 每个rabbitTemplate只能有一个confirm-callback和return-callback*/

        template.setConfirmCallback(msgSendConfirmCallBack());
        //template.setReturnCallback(msgSendReturnCallback());
        /**
         * 使用return-callback时必须设置mandatory为true,或者在配置中设置mandatory-expression的值为true,可针对每次请求的消息去确定’mandatory’的boolean值,
         * 只能在提供’return -callback’时使用,与mandatory互斥*/
       //  template.setMandatory(true);
        return template;
    }

    /**
    消息确认机制
    Confirms给客户端一种轻量级的方式,能够跟踪哪些消息被broker处理,哪些可能因为broker宕掉或者网络失败的情况而重新发布。
    确认并且保证消息被送达,提供了两种方式:发布确认和事务。(两者不可同时使用)在channel为事务时,
    不可引入确认模式;同样channel为确认模式下,不可使用事务。
            * @date:2017/8/31
            * @className:ConnectionFactory
     * @author:Administrator
     * @description:
     */
    @Bean
    public MsgSendConfirmCallBack msgSendConfirmCallBack(){
        return new MsgSendConfirmCallBack();
    }

}
添加消息发送到交换机确认机制

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;

/**
 * <dl>
 * <dt>MsgSendConfirmCallBack</dt>
 * <dd>Description:</dd>
 * <dd>CreateDate: 2017/7/4</dd>
 * </dl>
 *
 * @author Administrator
 */
public class MsgSendConfirmCallBack implements RabbitTemplate.ConfirmCallback{
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println(" 回调id:" + correlationData);
        if (ack) {
            System.out.println("消息成功消费");
        } else {
            System.out.println("消息消费失败:" + cause+"\n重新发送");

        }
    }
}

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

/**
 * <dl>
 * <dt>MsgSendReturnCallback</dt>
 * <dd>Description:</dd>
 * <dd>CreateDate: 2017/7/4</dd>
 * </dl>
 *
 * @author Administrator
 */
public class MsgSendReturnCallback implements RabbitTemplate.ReturnCallback {
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        String msgJson  = new String(message.getBody());
        System.out.println("回馈消息:"+msgJson);
    }
}

添加消费的端

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;

public class MessageConsumer implements ChannelAwareMessageListener {

    private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);

    @Override
    public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws Exception {
        byte[] body = message.getBody();
        System.out.println("收到消息1 : " + new String(body));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费

    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;

public class MessageConsumer2 implements ChannelAwareMessageListener {
    private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);

    @Override
    public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws Exception {
        byte[] body = message.getBody();
        System.out.println("收到消息2 : " + new String(body));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费

    }
}
添加客户端

import com.fumubang.rabbitmq.config.ConnectionFactoryConfigure;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

/**
 * <dl>
 * <dt>SendController</dt>
 * <dd>Description:</dd>
 * <dd>CreateDate: 2017/9/1</dd>
 * </dl>
 *
 * @author Administrator
 */
@Controller
public class SendController{

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping("/send")
    public String send3() throws UnsupportedEncodingException {
        String uuid = UUID.randomUUID().toString();
        CorrelationData correlationId = new CorrelationData(uuid);
        rabbitTemplate.convertAndSend(ConnectionFactoryConfigure.EXCHANGE, ConnectionFactoryConfigure.ROUTINGKEY2, "哈哈", correlationId);
        return uuid;
    }

}

可以通过postman或者单元测试进行调用http://localhost:端口号/send,返回结果如下

收到消息2 : 哈哈
 回调id:CorrelationData [id=6d4b1b12-185e-4d21-aa71-8b2841fb8f09]
消息成功消费



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值