參考: https://blog.csdn.net/u013871100/article/details/82982235
1 起步依賴
pom.xml中 引入rabbitmq依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2 配置文件
application.properties中添加下面配置
# rabbitmq配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.listener.concurrency=1
spring.rabbitmq.listener.max-concurrency=2
spring.rabbitmq.listener.prefetch=5
#rabbitmq隊列、交換器、routingkey配置 (下面是其中一個queue的配置)
rabbitmq.mq.person.handler.exchange=whir.test.boot.event.person.exchange
rabbitmq.mq.person.handler.queue=whir.test.boot.event.person.queue
rabbitmq.mq.person.handler.routingkey=whir.test.boot.event.person.routingkey
說明:
其中concurrency爲併發消費者初始值,max-concurrency爲併發消費者最大值,prefetch爲每個消費者每次監聽時可以拉取處理的消息數量。
3 消息發送組件、監聽器容器實現
@Configuration
public class RabbitmqConfig {
/**
* 併發消費者初始值
*/
@Value("${spring.rabbitmq.listener.concurrency}")
private Integer rabbitMqConcurrency;
/**
* 併發消費者最大值
*/
@Value("${spring.rabbitmq.listener.max-concurrency}")
private Integer maxMqConcurrency;
/**
* 每個消費者每次監聽時可拉取處理的消息數量
*/
@Value("${spring.rabbitmq.listener.prefetch}")
private Integer prefetch;
@Autowired
private CachingConnectionFactory connectionFactory;
@Autowired
private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;
@Autowired
private RabbitConfirmCallback rabbitConfirmCallback;
/**
* RabbitTemplate是消息發送組件
*/
@Bean
public RabbitTemplate rabbitTemplate(){
//消息發佈成功後是否有回調
connectionFactory.setPublisherConfirms(Boolean.TRUE);
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//mandatory參數爲true時,如果消息無法匹配到queue,消息會返回給消息發送者
rabbitTemplate.setMandatory(Boolean.TRUE);
//消息發送成功後的回調
rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
return rabbitTemplate;
}
/**
* SimpleRabbitListenerContainerFactory是監聽器容器
*/
@Bean("multiListenerContainer")
public SimpleRabbitListenerContainerFactory multiListenerContainer(){
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factoryConfigurer.configure(factory,connectionFactory);
//消息轉換器
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setAcknowledgeMode(AcknowledgeMode.NONE);
factory.setConcurrentConsumers(rabbitMqConcurrency);
factory.setMaxConcurrentConsumers(maxMqConcurrency);
factory.setPrefetchCount(prefetch);
return factory;
}
}
/**
* 消息發送成功後callback實現類
*
**/
@Component
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {
private static final Logger log = LoggerFactory.getLogger(RabbitConfirmCallback.class);
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
log.info("消息發送成功:correlationData={},ack={},cause={}",correlationData,b,s);
}
}
說明: RabbitTemplate是消息發送組件,SimpleRabbitListenerContainerFactory是監聽器容器,用來存放實例化的監聽器。
4 聲明隊列並綁定交換器
/**
* @description: Person處理隊列聲明配置類
* @create: 2019-12-03 11:50
**/
@Configuration
public class PersonHandlerQueueDeclare {
@Value("${rabbitmq.mq.person.handler.queue}")
private String personQueueName;
@Value("${rabbitmq.mq.person.handler.exchange}")
private String personExchangeName;
@Value("${rabbitmq.mq.person.handler.routingkey}")
private String personRoutingKey;
@Bean("personHandlerQueue")
public Queue personHandlerQueue(){
return new Queue(personQueueName);
}
@Bean("personHandlerExchange")
public DirectExchange personHandlerExchange(){
return new DirectExchange(personExchangeName);
}
@Bean("personHandlerBinding")
public Binding personHandlerBinding(){
return BindingBuilder.bind(personHandlerQueue()).to(personHandlerExchange()).with(personRoutingKey);
}
}
說明: PersonHandlerQueueDeclare聲明queue、exchange,並把queue綁定到exchange上, 綁定之後隊列和交換器就可以在rabbitmq管理後臺查看到。
5 消費者監聽消息
/**
* @description: Person處理消費者
* @create: 2019-12-03 12:18
**/
@Component
public class PersonHandlerConsume {
private Logger log = LoggerFactory.getLogger(PersonHandlerConsume.class);
@Autowired
private ObjectMapper objectMapper;
@RabbitListener(queues = "${rabbitmq.mq.person.handler.queue}",containerFactory = "multiListenerContainer")
public void handler(@Payload byte[] message){
Person person = null;
try {
person = objectMapper.readValue(message, Person.class);
log.info("監聽到消息,age={},name={},id={}", person.getAge(),person.getName(),person.getId());
} catch (IOException e) {
log.warn("監聽消息異常",e);
}
}
}
6 生產者消息發送
@RestController
@RequestMapping("/mq")
public class QueueController {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private Environment env;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping("/test")
public String mqSend(){
//初始化數據
Person person = new Person();
person.setName("zhangsan");
person.setAge(123);
person.setId(2);
Message message= null;
try {
//發送消息
rabbitTemplate.setExchange(env.getProperty("rabbitmq.mq.person.handler.exchange"));
rabbitTemplate.setRoutingKey(env.getProperty("rabbitmq.mq.person.handler.routingkey"));
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
CorrelationData correlationData = new CorrelationData();
correlationData.setId(String.valueOf(person.getId()));
message = MessageBuilder.withBody(objectMapper.writeValueAsBytes(person)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
message.getMessageProperties().setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, MessageProperties.CONTENT_TYPE_JSON);
rabbitTemplate.convertAndSend(env.getProperty("rabbitmq.mq.person.handler.routingkey"),message,correlationData);
} catch (Exception e) {
e.printStackTrace();
}
return "123";
}
}
7 演示
請求地址:http://localhost:8080/mq/test
控制檯打印日誌如下: