rabbitMQ学习笔记(七)——整合springboot

pom.xml

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


config类

config类是来完成声明交换机、声明队列、绑定交换机和队列这三个步骤的。代码如下:

@Configuration
public class RabbitmqFanoutConfig {

    private String EXCHANGE_NAME = "fanoutExchange";
    private String FANOUT_SMS_QUEUE = "fanout_sms_queue";
    private String FANOUT_EMAIL_QUEUE = "fanout_email_queue";

    //声明交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange(EXCHANGE_NAME);
    }

    //声明队列
    @Bean
    public Queue fanoutEmailQueue(){
        return new Queue(FANOUT_EMAIL_QUEUE);
    }

    @Bean
    public Queue fanoutSmsQueue(){
        return new Queue(FANOUT_SMS_QUEUE);
    }
    
    //绑定交换机和队列
    @Bean
    Binding bindingExchangeEmail(Queue fanoutEmailQueue, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutEmailQueue).to(fanoutExchange);
    }
    
    @Bean
    Binding bindingExchangeSms(Queue fanoutSmsQueue, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutSmsQueue).to(fanoutExchange);
    }
}

配置类的思路是,将整个配置类用@Configuration标注,作为bean注入到IOC容器中,而其中的@Bean标签下的每一个方法都会作为单独的bean注入到IOC容器当中。


首先声明交换机,根据前几节的声明可知,声明交换机同时需要有交换机名称和交换模式。 ```java channel.exchangeDeclare(EXCHANGE_ROUTING_INFO, BuiltinExchangeType.DIRECT); ``` 在本例中,由于使用@Bean注入,交换机名称默认为方法名,若需要自定义则可以用@Bean(" ")在其中指定。而交换机模式指定则是返回的方法,若是topics模式则返回TopicExchange;若是Direct模式则返回DirectExchange。如下所示:
@Bean
public TopicExchange topicExchange(){
    return new TopicExchange(EXCHANGE_NAME);
}

@Bean
public DirectExchange directExchange(){
    return new DirectExchange(EXCHANGE_NAME);
}

其次是声明队列,在前几节声明队列时,要指定队列名称、持久化、是否独占连接,、是否自动删除、一些扩展参数。如:

channel.queueDeclare(QUEUENAME,true,false,false,null);

而在本例中,是通过Queue的构造方法来实现队列的配置。

@Bean
    public Queue fanoutEmailQueue(){
        return new Queue(FANOUT_EMAIL_QUEUE);
    }

最后是绑定交换机和队列,这一步需要有三个参数,队列名称、交换机名称和routingKey。代码如下:

@Bean
    Binding bindingExchangeEmail(Queue fanoutEmailQueue, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutEmailQueue).to(fanoutExchange);
    }

方法里的参数对应的实际是IOC容器里的声明队列的ID和交换机ID。通过BindingBuilder中bind方法构建一个BindingBuilder的内部类——DestinationConfigurer类。(注意bind方法是静态方法)。BindingBuilder代码如下(节选):

public final class BindingBuilder {

	private BindingBuilder() {
	}

	public static DestinationConfigurer bind(Queue queue) {
		return new DestinationConfigurer(queue.getName(), DestinationType.QUEUE);
	}

	public static DestinationConfigurer bind(Exchange exchange) {
		return new DestinationConfigurer(exchange.getName(), DestinationType.EXCHANGE);
	}

之后调用DestinationConfigurer类中的to方法完成交换机与队列的绑定。代码如下:

public static final class DestinationConfigurer {

		protected final String name; // NOSONAR

		protected final DestinationType type; // NOSONAR

		DestinationConfigurer(String name, DestinationType type) {
			this.name = name;
			this.type = type;
		}

		public Binding to(FanoutExchange exchange) {
			return new Binding(this.name, this.type, exchange.getName(), "", new HashMap<String, Object>());
		}

		public HeadersExchangeMapConfigurer to(HeadersExchange exchange) {
			return new HeadersExchangeMapConfigurer(this, exchange);
		}

		public DirectExchangeRoutingKeyConfigurer to(DirectExchange exchange) {
			return new DirectExchangeRoutingKeyConfigurer(this, exchange);
		}

		public TopicExchangeRoutingKeyConfigurer to(TopicExchange exchange) {
			return new TopicExchangeRoutingKeyConfigurer(this, exchange);
		}

		public GenericExchangeRoutingKeyConfigurer to(Exchange exchange) {
			return new GenericExchangeRoutingKeyConfigurer(this, exchange);
		}
	}

上述代码可知重构了许多to方法,实际上,其他交换机模式都需要指定路由key,而这个路由key的指定。当to方法传入的是DirectExchange参数时,返回的DirectExchangeRoutingKeyConfigurer类如下:

public static final class DirectExchangeRoutingKeyConfigurer extends AbstractRoutingKeyConfigurer {

		DirectExchangeRoutingKeyConfigurer(DestinationConfigurer destination, DirectExchange exchange) {
			super(destination, exchange.getName());
		}

		public Binding with(String routingKey) {
			return new Binding(destination.name, destination.type, exchange, routingKey,
					Collections.<String, Object>emptyMap());
		}

可见其中有一个with方法,这便是指定routingKey的方法。绑定完成。至此,config的配置就结束了。



生产者实现

生产者代码就十分简单,代码如下:

@Component
public class HelloProvider {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    private String EXCHANGE_NAME = "fanoutExchange";

    public void send(){
        rabbitTemplate.convertAndSend(EXCHANGE_NAME,"","你好世界!");
        System.out.println("消息已经发送!");
    }
}

消息发送使用springboot中的rabbitmq的模板类RabbitTemplate中的convertAndSend方法发送消息。代码如下:

@Override
	public void convertAndSend(String exchange, String routingKey, final Object object) throws AmqpException {
		convertAndSend(exchange, routingKey, object, (CorrelationData) null);
	}

这里发送可指定routingKey。由于本例是订阅模式,因此routingKey为空。



消费者实现

消费者实现同样也很简单:

@Component
@RabbitListener(queuesToDeclare = @Queue("fanout_sms_queue")) //代表监听,消费者。
public class SmsConsumer {

    @RabbitHandler
    public void consume(String message){
        System.out.println("sms消费者消息为:" + message);
    }
}

通过注解@RabbitListener表明本类是消费者,启动后开启监听,监听队列在注解中用参数指定。类中方法可用@RabbitHandler注解表明是回调方法,接收到消息后执行该方法。



注意:如果生产者消费者是分布式的项目,要在生产者消费者代码中都添加config类,这样的话不管谁先启动,都能够顺利的将配置加载到rabbitMQ服务器上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值