RabbitMQ-StringAMQP入门

StringAMQP入门

  • 导入依赖

    		<!--AMQP依赖,包含RabbitMQ-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
            </dependency>
    
  • 消息提供者(publisher)

    • 在application.yml中添加相关配置

      spring:
        rabbitmq:
          host: 121.199.23.164 #主机名
          port: 5672 # 端口
          virtual-host: /  # 虚拟主机
          username: itcast # 用户名
          password: 123321 # 密码
      
    • 测试

      /**
       * StringAMQP的测试
       */
      
      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class SpringAmqpTest {
      
          @Autowired
          private RabbitTemplate rabbitTemplate;
      
          @Test
          public void testSimpleQueue(){
              String queueName = "simple.queue";
              String message = "hello, spring amqp!";
              rabbitTemplate.convertAndSend(queueName,message);
              System.out.println("发送成功!");
          }
      
      }
      
  • 消息消费者(comsumer)

    • 在application.yml中添加相关配置

      spring:
        rabbitmq:
          host: 121.199.23.164 #主机名
          port: 5672 # 端口
          virtual-host: /  # 虚拟主机
          username: itcast # 用户名
          password: 123321 # 密码
      
    • 书写配置类,编辑消费逻辑

      @Component
      public class StringRabbitListener {
      
          @RabbitListener( queues = "simple.queue")
          public void listenerSimpleQueue(String msg){
              System.out.println("接收到消息:【" + msg + "】");
          }
      
      }
      
    • 启动spring boot 启动类,测试。

注意:消息一旦消费就会从队列删除,RabbmitMQ没有消息回溯功能。

发布订阅-FanoutExchange

FanoutExchange会将接收到的消息路由到每一个跟其绑定的queue

  • 在consumer 中创建配置类
@Configuration
public class FanoutConfig {

    /**
     * 声明交换机 itcast.fanout
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("itcast.fanout");
    }

    /**
     * 声明 队列1 fanout.queue1
     * @return
     */
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue1");
    }

    /**
     * 绑定 队列1 到交换机
     * @param fanoutQueue1
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding binding(Queue fanoutQueue1,FanoutExchange fanoutExchange){
        return BindingBuilder
                .bind(fanoutQueue1)
                .to(fanoutExchange);
    }

    /**
     * 声明 队列1 fanout.queue2
     * @return
     */
    @Bean
    public Queue fanoutQueue2(){
        return new Queue("fanout.queue2");
    }

    /**
     * 绑定 队列2 到交换机
     * @param fanoutQueue2
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding binding2(Queue fanoutQueue2,FanoutExchange fanoutExchange){
        return BindingBuilder
                .bind(fanoutQueue2)
                .to(fanoutExchange);
    }
}

  • 在consumer 中监听两个队列
    @Component
	public class StringRabbitListener {
        @RabbitListener( queues = "fanout.queue1")
        public void listenerFanoutQueue1(String msg){
            System.out.println("接收到消息1:【" + msg + "】");
        }

        @RabbitListener( queues = "fanout.queue2")
        public void listenerFanoutQueue2(String msg){
            System.out.println("接收到消息2:【" + msg + "】");
        }
    }
  • 在publisher 中编写消息提供
    @Test
    public void testSendFanoutExchange() throws InterruptedException {
        // 交换机名称
        String exchangeName = "itcast.fanout";
        String message = "fanout.queue";
        // 消息
        rabbitTemplate.convertAndSend(exchangeName,"",message);
    }

发布订阅-DirectExchange

DirectExchange 会将接收到的消息根据规则路由到指定的 queue ,因此成为路由模式(routes)

  • 每一个Queue 都与Exchange 设置一个BindingKey
  • 发布者发送消息时,指定消息的RoutingKey
  • Exchange 将消息路由到BindingKey 与消息RoutingKey一致的队列

基于@RabbitListener注解来声明队列和交换机的方式:

  • 在consumer 编写listener类
 	@Component
	public class StringRabbitListener {
	
                 @RabbitListener(bindings = @QueueBinding(
                                                        value = @Queue("direct.queue1"),
                                                        exchange = @Exchange("itcast.direct"),
                                                        key = {"red","blue"}
                ))
                public void testDirectQueue1(String msg){
                    System.out.println("接收到消息direct.queue1为:【" + msg + "】");
                }



                @RabbitListener(bindings = @QueueBinding(
                               value = @Queue("direct.queue2"), //交换机名字
                               exchange = @Exchange(value = "itcast.direct",type = ExchangeTypes.DIRECT), //队列名称; 默认就是direct
                                key = {"red","yellow"} //指定的key名
                ))
                public void testDirectQueue2(String msg){
                    System.out.println("接收到消息direct.queue2为:【" + msg + "】");
                }   
    }
  • 在publisher 中编写测试
	@Test
    public void testSendDirectExchange() throws InterruptedException {
        // 交换机名称
        String exchangeName = "itcast.direct";
        String message = "hello , red";
        // 消息 //red 就是指定的key名称
        rabbitTemplate.convertAndSend(exchangeName,"red",message);
    }

发布订阅-TopicExchange

TopicExchange和DirectExchange类似,区别在于routingkey必须是多个单词的列表,并且以 . 分割

Queue与Exchange指定BindingKey时可以使用通配符:

  • # 代指0个或多个单词
  • * 代值一个单词

在consumer 编写listener类

	@Component
	public class StringRabbitListener {
	
			@RabbitListener(bindings = @QueueBinding(
              value = @Queue("direct.topic1"), //交换机名字
              exchange = @Exchange(value = "itcast.topic",type = ExchangeTypes.TOPIC), //队列名称
              key = "china.#" //指定的key名
    		))
            public void testTopicQueue1(String msg){
                System.out.println("接收到消息topic.topic1为:【" + msg + "】");
            }

            @RabbitListener(bindings = @QueueBinding(
                    value = @Queue("direct.topic2"), //交换机名字
                    exchange = @Exchange(value = "itcast.topic",type = ExchangeTypes.TOPIC), //队列名称
                    key = "#.news" //指定的key名
            ))
            public void testTopicQueue2(String msg){
                System.out.println("接收到消息topic.topic2为:【" + msg + "】");
            }

	
	}

在publisher测试

	@Test
    public void testSendTopicExchange() throws InterruptedException {
        // 交换机名称
        String exchangeName = "itcast.topic";
        String message = "qinqin公司上市了!";
        // 消息
        rabbitTemplate.convertAndSend(exchangeName,"china.news",message);
    }

消息转换器

Spring的对消息对象的处理是由org.springframeworkamqp.support.converter.MessageConverter来处理的。而默认实现是SimpleMessageConverter,基于JDK的ObjectOutputStream完成序列化。

如果要修改只需要定义一个MessageConverter 类型的Bean即可。推荐用SON方式序列化,步骤如下:

  • publisher 的pom导入依赖:
		<dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.9.10</version>
        </dependency>
  • 在 启动类中加入声明MessageConverter

    注意:导入的包为import org.springframework.amqp.support.converter.MessageConverter

	@Bean
    public MessageConverter MessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
  • 编写消息提供者
	@Test
    public void testSendObjctQueue() throws InterruptedException {
        // 交换机名称
        String exchangeName = "itcast.object";
        Map<String, Object> msg = new HashMap<>();
        msg.put("name","柳岩");
        msg.put("age","18");
        // 消息
        rabbitTemplate.convertAndSend(exchangeName,msg);
    }
  • consumer 中导入依赖:
		<dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.9.10</version>
        </dependency>
  • 在 启动类中加入声明MessageConverter

    注意:导入的包为import org.springframework.amqp.support.converter.MessageConverter

	@Bean
    public MessageConverter MessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
  • 定义消费者,监听消息
	@RabbitListener( queues = "itcast.object")
    public void listenerObjectQueue(Map<String,Object> msg){ //注意消费者的类型
        System.out.println("接收到消息itcast.object为::【" + msg + "】");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值