SpringBoot与RabbitMQ的整合

文章目录[隐藏]

Publish/Subscribe(发布订阅模式)

以用户注册成功后,同时发送邮件通知和短信通知场景为例,实现整合

基于API的方式

定制消息发送组件
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter08ApplicationTests {
    @Autowired
    private AmqpAdmin amqpAdmin;

    /**
     * 使用AmqpAdmin管理员API定制消息组件
     */
    @Test
    public void amqpAdmin() {
        // 1、定义fanout类型的交换器
        amqpAdmin.declareExchange(new FanoutExchange("fanout_exchange"));
        // 2、定义两个默认持久化队列,分别处理email和sms
        amqpAdmin.declareQueue(new Queue("fanout_queue_email"));
        amqpAdmin.declareQueue(new Queue("fanout_queue_sms"));
        // 3、将队列分别与交换器进行绑定
        amqpAdmin.declareBinding(new Binding("fanout_queue_email",Binding.DestinationType.QUEUE,"fanout_exchange","",null));
        amqpAdmin.declareBinding(new Binding("fanout_queue_sms",Binding.DestinationType.QUEUE,"fanout_exchange","",null));
    }
}

执行单元测试,访问RabbitMQ的可视化管理界面:

可以看到,出现了一个名为fanout_exchange的交换机,点击查看:

展示有其具体信息,其中,红框内的内容为与之绑定的两个消息队列。切换至Queues面板,查看定制生成的消息的队列信息

消息发送者发送消息

传递一个实体类封装的消息

@Data
public class User {
    private Integer id;
    private String username;
}

测试类中

@Test
public void psubPublisher() {
    User user=new User();
    user.setId(1);
    user.setUsername("石头");
    rabbitTemplate.convertAndSend("fanout_exchange","",user);
}

此时执行测试方法,会出现异常:

SimpleMessageConverter only supports String,byte[] and Serializable payloads.

此时可以实现序列化,或者定制其他类型的消息转化器:

@Configuration
public class RabbitMQConfig {
    /**
     * 定制JSON格式的消息转换器
     *
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}

再次执行测试,会出现如下效果:

目前未提供消息消费者,因此消息会暂存至队列

消息消费者接收消息
public class RabbitMQService {
    /**
     * Publish/Subscribe工作模式接收,处理邮件业务
     * @param message
     */
    @RabbitListener(queues = "fanout_queue_email")
    public void psubConsumerEmail(Message message) {
        byte[] body = message.getBody();
        String s = new String(body);
        System.out.println("邮件业务接收到消息: "+s);

    }
    /**
     * Publish/Subscribe工作模式接收,处理短信业务
     * @param message
     */
    @RabbitListener(queues = "fanout_queue_sms")
    public void psubConsumerSms(Message message) {
        byte[] body = message.getBody();
        String s = new String(body);
        System.out.println("短信业务接收到消息: "+s);
    }
}

此时启动整个项目,就会对所监听的队列:“fanout_queue_email”和“fanout_queue_sms”中的消息进行消费,效果即为打印至控制台。

至此,使用api方式进行一条信息的发送、消息中间件的存储,以及消息消费的发布/订阅工作模式的业务案例已经实现

基于配置类的方式

@Configuration
public class RabbitMQConfig {
    /**
     * 定制JSON格式的消息转换器
     *
     * @return
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 使用基于配置类的方式定制消息中间件
     *
     * @return
     */
    // 1、定义fanout类型的交换器
    @Bean
    public Exchange fanout_exchange() {
        return ExchangeBuilder.fanoutExchange("fanout_exchange").build();
    }

    // 2、定义两个不同名称的消息队列
    @Bean
    public Queue fanout_queue_email() {
        return new Queue("fanout_queue_email");
    }

    @Bean
    public Queue fanout_queue_sms() {
        return new Queue("fanout_queue_sms");
    }

    // 3、将两个不同名称的消息队列与交换器进行绑定
    @Bean
    public Binding bindingEmail() {
        return BindingBuilder.bind(fanout_queue_email()).to(fanout_exchange()).with("").noargs();
    }

    @Bean
    public Binding bindingSms() {
        return BindingBuilder.bind(fanout_queue_sms()).to(fanout_exchange()).with("").noargs();
    }

}

该步骤完成了消息组建的定制,此外,还需进行消息发送者和消息消费者的编写,上一种方式已经实现,可以直接使用,测试效果完全相同

基于注解的方式

@Service
public class RabbitMQService {
//    /**
//     * Publish/Subscribe工作模式接收,处理邮件业务
//     * @param message
//     */
//    @RabbitListener(queues = "fanout_queue_email")
//    public void psubConsumerEmail(Message message) {
//        byte[] body = message.getBody();
//        String s = new String(body);
//        System.out.println("邮件业务接收到消息: "+s);
//
//    }
//    /**
//     * Publish/Subscribe工作模式接收,处理短信业务
//     * @param message
//     */
//    @RabbitListener(queues = "fanout_queue_sms")
//    public void psubConsumerSms(Message message) {
//        byte[] body = message.getBody();
//        String s = new String(body);
//        System.out.println("短信业务接收到消息: "+s);
//    }

    /**
     *  **使用基于注解的方式实现消息服务
     * 1.1、Publish/Subscribe工作模式接收,处理邮件业务
     * @param user
     */
    @RabbitListener(bindings =@QueueBinding(value =@Queue("fanout_queue_email"), exchange =@Exchange(value = "fanout_exchange",type = "fanout")))
    public void psubConsumerEmailAno(User user) {
        System.out.println("邮件业务接收到消息: "+user);
    }
    /**
     * 1.2、Publish/Subscribe工作模式接收,处理短信业务
     * @param user
     */
    @RabbitListener(bindings =@QueueBinding(value =@Queue("fanout_queue_sms"),exchange =@Exchange(value = "fanout_exchange",type = "fanout")))
    public void psubConsumerSmsAno(User user) {
        System.out.println("短信业务接收到消息: "+user);
    }
}

该方式中,@RabbitListener定制了消息组件的消费者,其运行效果完全相同

Rounting(路由模式)

基于注解方式定制消息组件和消息消费者

/**
 * 2.1、路由模式消息接收,处理error级别日志信息
 *
 * @param message
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue("routing_queue_error"),
        exchange = @Exchange(value = "routing_exchange", type = "direct"),
        key = "error_routing_key"))
public void routingConsumerError(String message) {
    System.out.println("接收到error级别日志消息: " + message);
}

/**
 * 2.2、路由模式消息接收,处理info、error、warning级别日志信息
 *
 * @param message
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue("routing_queue_all"),
        exchange = @Exchange(value = "routing_exchange", type = "direct"),
        key = {"error_routing_key", "info_routing_key", "warning_routing_key"}))
public void routingConsumerAll(String message) {
    System.out.println("接收到info、error、warning等级别日志消息: " + message);
}

注解定制了路由模式下的消息服务组件,Rounting路由模式下,交换器类型type属性为direct,且必须指定key属性(每个消息队列可以映射多个路由键)

消息发送者发送消息

使用RabbitTemplate实现Rounting路由模式下的消息发送:

/**
 * 2、Routing工作模式消息发送端
 */
@Test
public void routingPublisher() {
    String message = "This is a error message";
    rabbitTemplate.convertAndSend("routing_exchange", "error_routing_key", message);
}

执行测试方法,效果如下:

修改rountKey及信息,如下,再次测试

/**
 * 2、Routing工作模式消息发送端
 */
@Test
public void routingPublisher2() {
    String message = "This is a info message";
    rabbitTemplate.convertAndSend("routing_exchange", "info_routing_key", message);
}

也自动生成了Rounting路由模式下的消息组件,并进行了自动绑定:

Topics(通配符模式)

使用基于注解的方式定制消息组件和消息消费者

/**
 * 3.1、通配符模式消息接收,进行邮件业务订阅处理
 *
 * @param message
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue("topic_queue_email"),
        exchange = @Exchange(value = "topic_exchange",
                type = "topic"), key = "info.#.email.#"))
public void topicConsumerEmail(String message) {
    System.out.println("接收到邮件订阅需求处理消息: " + message);
}

/**
 * 3.2、通配符模式消息接收,进行短信业务订阅处理
 *
 * @param message
 */
@RabbitListener(bindings = @QueueBinding(value = @Queue("topic_queue_sms"),
        exchange = @Exchange(value = "topic_exchange",
                type = "topic"), key = "info.#.sms.#"))
public void topicConsumerSms(String message) {
    System.out.println("接收到短信订阅需求处理消息: " + message);
}

使用方式与Rounting基本一致,主要是将交换机的类型type修改为topic,以及使用通配符的样式指定路由键。

消息发送者发送消息

使用RabbitTemplate实现Topics通配符模式下的消息发送:

/**
     * 3、Topcis工作模式消息发送端
     */
    @Test
    public void topicPublisher() {
        // 1、只发送邮件订阅用户消息
//        rabbitTemplate.convertAndSend("topic_exchange","info.email","topics send  email message");
        // 2、只发送短信订阅用户消息
//     rabbitTemplate.convertAndSend("topic_exchange","info.sms","topics send  sms message");
        // 3、发送同时订阅邮件和短信的用户消息
        rabbitTemplate.convertAndSend("topic_exchange", "info.email.sms", "topics send  email and sms message");
    }

测试结果类似,不在展示,同时也进行了自动绑定

源码下载

文件下载

  文件名称:本节代码.zip  文件大小:2.62MB
  下载声明:本站文件大多来自于网络,仅供学习和研究使用,不得用于商业用途,如有版权问题,请联系博主!
  下载地址:点击下载

提取码

注意:本段内容须“登录”后方可查看!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值