RabbitMQ-整合Spring AMQP实战

1. RabbitAdmin

  1. 概述
    1. 可以把RabbitAdmin作为Spring的一个Bean,然后细粒度的操作RabbitMQ。
    2. 底层调用的是RabbitTemplate的execute方法,然后execute调用RabbitMQ的其它基础操作。
  2. pom文件配置
<!--RabbitMQ-->
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>3.6.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. Rabbit和AMQP的配置:RabbitAdmin 's AutoStartup必须设置为true, 否则Spring启动时, 不会把RabbitAdmin注入到Spring容器中. 通过@Bean的方式, 当Spring启动的时候, 会自动创建这些Bean的Exchange、queue
@Configuration
@ComponentScan({"com.boot.rabbitmq.spring.*"})public class RabbitMQConfig {

    @Bean
    public ConnectionFactory connectionFactory() {        
    	CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses("127.0.0.1:5672");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");

        return connectionFactory;
    }
    
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {        
    	RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 必须设置为true, 否则Spring启动时, 不会把RabbitAdmin注入到Spring容器中.
        rabbitAdmin.setAutoStartup(true);

        return rabbitAdmin;
    }
    
    @Bean
	public TopicExchange exchange001() {    
		return new TopicExchange("exchange001", true, false);
	}
	
	@Bean
	public Queue queue001() {    
		return new Queue("queue001", true);
	}
	
	@Bean
	public Binding binding001() {    
		return BindingBuilder
	            .bind(queue001()) // Queue
	            .to(exchange001()) // Exchange
	            .with("spring.*"); // Routing key
	}
 }

2. RabbitTemplate

  1. 概述:
    1. 是提供与SpringAMQP整合的时候进行发送消息的关键类。
    2. 该类包含了:可靠性投递消息方法,回调监听消息接口(ConfirmCallback)、返回值确认接口(ReturnCallback)等等。
  2. Config配置
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {        
    	RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        // 可以设置很多回到方法.
		// rabbitTemplate.setConfirmCallback();
		// rabbitTemplate.setReturnCallback();
        return rabbitTemplate;
    }
  1. 基础API使用
public class RabbitTemplateTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMessage() {        
    	// 1.设置消息头.
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.getHeaders().put("header1", "HEADER!");

        String messageBody = "Hello RabbitTemplate!";
        // 2.设置休息体.
        Message message = new Message(messageBody.getBytes(), messageProperties);

        // 3.发送消息.
        rabbitTemplate.convertAndSend("exchange001", "spring.amqp", message, message1 -> {            
        	// 对Message的转换.
            message1.getMessageProperties().getHeaders().put("header1", "NEW HEADER!");
            message1.getMessageProperties().getHeaders().put("header2", "HEADER2!");
            return message1;
        });
    }
    
    /**
     * 多种发送消息形式.
     */
    public void sendMessage2() {        // 1.设置消息头.
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.getHeaders().put("header1", "HEADER!");

        String messageBody = "Hello RabbitTemplate!";
        // 2.设置休息体.
        Message message = new Message(messageBody.getBytes(), messageProperties);

        // 3.1 发送的是封装好的Message对象.
        rabbitTemplate.send("exchange001", "spring.amqp", message);

        // 3.2 直接发送字符串.
        rabbitTemplate.convertAndSend("exchange001", "spring.amqp", "Hello world!");
    }
 }

3. SimpleMessageListenerContainer(消息监听容器;可以运行中, 动态修改)

  1. 概述:

    1. 可以让消费者监听队列(多个),自动启动,自动声明功能。
    2. 设置事务特性、事务管理器、事务属性、事务容量(并发)、是否开启事务、回滚消息等。
    3. 设置消费者数量、最小最大数量、批量消费。
    4. 设置消息确认和自动确认模式、是否重回队列、异常捕获handler函数。
    5. 设置消费者标签生成策略、是否独占模式、消费者属性等。
    6. 设置具体的监听器、消息转换器等。
  2. 配置

@Bean
public SimpleMessageListenerContainer simpleMessageListenerContainer(ConnectionFactory connectionFactory) {    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
    container.setQueues(queue001(), queue002()); // 设置监听多个queue
    container.setConcurrentConsumers(1); // 设置消费端数量
    container.setMaxConcurrentConsumers(5); // 设置最大的消费者数量
    container.setDefaultRequeueRejected(false); // 是否重回队列
    container.setAcknowledgeMode(AcknowledgeMode.AUTO); // 设置签收模式
    container.setConsumerTagStrategy(queue -> queue + "_" + UUID.randomUUID()); // 设置消费端标签策略

    // 设置消息的监听
    container.setMessageListener(message -> System.out.println("消费端消息: " + new String(message.getBody())));
    return container;
}

4. MessageListenerAdapter(消息监听适配器)

  1. 案例:自定义MessageListenerAdapter以及MessageConverter 。
// 通过自定义listenerAdapter和转换DefaultListenerMethod参数类型.
MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(new MyMessageListenerAdapter());
listenerAdapter.setDefaultListenerMethod("defaultListener");
listenerAdapter.setMessageConverter(new MyMessageConverter());
container.setMessageListener(listenerAdapter);


/**
 * {@link org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter#setMessageConverter(MessageConverter)}
 */
public class MyMessageConverter implements MessageConverter {
    @Override
    public Message toMessage(Object message, MessageProperties messageProperties) throws MessageConversionException {        
    	return new Message(message.toString().getBytes(), messageProperties);
    }
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {        
    	String contentType = message.getMessageProperties().getContentType();
        if (contentType != null && contentType.contains("text")) {            
        	return new String(message.getBody());
        }
        
        return message.getBody();
    }
}
  1. 案例:
/**
 * 队列名称和方法名称一一对应
 * 自定义的listenerAdapter, 需要有对应的方法名称.
 * 这样就是队列触发的是, 对应的方法。
 */
MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(new MyMessageListenerAdapter());
Map<String, String> queueOrTagToMethodName =new HashMap<>();
queueOrTagToMethodName.put("queue001", "method1");
queueOrTagToMethodName.put("queue002", "method2");
queueOrTagToMethodName.put("queue003", "method3");

listenerAdapter.setQueueOrTagToMethodName(queueOrTagToMethodName);

5. MessageConverter(消息转换器)

  1. 概述:需要实现MessageConverter接口,然后,重写fromMessagetoMessage方法。
  2. 转换器:
    1. JSON转换器:Jackson2JsonMessageConverter:进行java对象的转换功能。
    2. DefaultJackson2JavaTypeMapper映射器:进行java对象的映射关系。
    3. 自定义二进制转换器:比如图片、PDF、PPT、流媒体。
  3. TextConverter:
/**
 * {@link org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter#setMessageConverter(MessageConverter)}
 */
public class MyMessageConverter implements MessageConverter {
    @Override
    public Message toMessage(Object message, MessageProperties messageProperties) throws MessageConversionException {        
    	return new Message(message.toString().getBytes(), messageProperties);
    }
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {        
    	String contentType = message.getMessageProperties().getContentType();
        if (contentType != null && contentType.contains("text")) {            
        	return new String(message.getBody());
        }
        
        return message.getBody();
    }
}
  1. JSON格式的转换器
// 通过自定义listenerAdapter和转换DefaultListenerMethod参数类型.
MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(new MyMessageListenerAdapter());
listenerAdapter.setDefaultListenerMethod("defaultListener");
listenerAdapter.setMessageConverter(new MyMessageConverter());
container.setMessageListener(listenerAdapter);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值