文章目录
1. RabbitAdmin
- 概述
- 可以把RabbitAdmin作为Spring的一个Bean,然后细粒度的操作RabbitMQ。
- 底层调用的是RabbitTemplate的execute方法,然后execute调用RabbitMQ的其它基础操作。
- 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>
- 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
- 概述:
- 是提供与SpringAMQP整合的时候进行发送消息的关键类。
- 该类包含了:可靠性投递消息方法,回调监听消息接口(ConfirmCallback)、返回值确认接口(ReturnCallback)等等。
- Config配置
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
// 可以设置很多回到方法.
// rabbitTemplate.setConfirmCallback();
// rabbitTemplate.setReturnCallback();
return rabbitTemplate;
}
- 基础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(消息监听容器;可以运行中, 动态修改)
-
概述:
- 可以让消费者监听队列(多个),自动启动,自动声明功能。
- 设置事务特性、事务管理器、事务属性、事务容量(并发)、是否开启事务、回滚消息等。
- 设置消费者数量、最小最大数量、批量消费。
- 设置消息确认和自动确认模式、是否重回队列、异常捕获handler函数。
- 设置消费者标签生成策略、是否独占模式、消费者属性等。
- 设置具体的监听器、消息转换器等。
-
配置
@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(消息监听适配器)
- 案例:自定义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();
}
}
- 案例:
/**
* 队列名称和方法名称一一对应
* 自定义的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(消息转换器)
- 概述:需要实现
MessageConverter
接口,然后,重写fromMessage
和toMessage
方法。 - 转换器:
- JSON转换器:Jackson2JsonMessageConverter:进行java对象的转换功能。
- DefaultJackson2JavaTypeMapper映射器:进行java对象的映射关系。
- 自定义二进制转换器:比如图片、PDF、PPT、流媒体。
- 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();
}
}
- JSON格式的转换器
// 通过自定义listenerAdapter和转换DefaultListenerMethod参数类型.
MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(new MyMessageListenerAdapter());
listenerAdapter.setDefaultListenerMethod("defaultListener");
listenerAdapter.setMessageConverter(new MyMessageConverter());
container.setMessageListener(listenerAdapter);