以direct交换机举例:
1.配置pom文件,主要是添加spring-boot-starter-amqp的支持
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置application.yml文件,配置rabbitmq的安装地址、端口以及账户信息
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: admin
password: admin
virtual-host: /
publisher-confirms: true #支持发布确认
publisher-returns: true #支持发布返回
listener:
simple:
acknowledge-mode: manual #采用手动应答
concurrency: 1 #指定最小的消费者数量
max-concurrency: 1 #指定最大的消费者数量
retry:
enabled: true #是否支持重试
3.rabbitmq配置类
package com.example.mq.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
/**
* rabbitmq配置
*/
@Configuration
public class RabbitConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtual-host}")
private String v_host;
/**
* direct直连,配置交换机、队列、路由键名称
*/
public static final String DIRECT_EXCHANGE="direct_exchange";
public static final String DIRECT_QUEUE="direct_queue";
public static final String DIRECT_ROUTING_KEY="direct_routing_key";
/**
* 获取mq的连接
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(v_host);
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
//===========================direct======================================
/**
* 声明Direct交换机 支持持久化.
* @return
*/
@Bean
public DirectExchange directExchange(){
return ExchangeBuilder.directExchange(DIRECT_EXCHANGE).durable(true).build();
}
/**
* 声明一个队列 支持持久化.
* @return
*/
@Bean
public Queue directQueue(){
return QueueBuilder.durable(DIRECT_QUEUE).build();
}
/**
* 通过绑定键 将指定队列绑定到一个指定的交换机
* @return
*/
@Bean
public Binding bindingDirect(){
return BindingBuilder.bind(directQueue()).to(directExchange()).with(DIRECT_ROUTING_KEY);
}
}
4.发送者
package com.example.mq.sender;
import com.example.mq.config.RabbitConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* 消息的发送者
*/
@Component
public class Sender implements RabbitTemplate.ConfirmCallback{
private static final Logger logger= LoggerFactory.getLogger(Sender.class);
private RabbitTemplate rabbitTemplate;
@Autowired
public Sender(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setConfirmCallback(this);
}
/**
* 发送消息
* @param message
*/
public void sendMsg(String message) {
CorrelationData correlationData = new CorrelationData();
correlationData.setId(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(RabbitConfig.DIRECT_EXCHANGE, RabbitConfig.DIRECT_ROUTING_KEY, message, correlationData);
logger.info("sendMsg :"+message);
logger.info("消息唯一id:"+correlationData.getId());
}
/**
* 消息确认
* @param correlationData 唯一标识,有了这个唯一标识,我们就知道可以确认(失败)哪一条消息了
* @param ack 是否投递成功
* @param cause 失败原因
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
String messageId = correlationData.getId();
//返回成功,表示消息被正常投递
if (ack) {
logger.info("信息投递成功,messageId:{}",messageId);
} else {
logger.info("消费信息失败,messageId:{} 原因:{}",messageId,cause);
}
}
}
5.接收者
package com.example.mq.receiver;
import com.example.mq.config.RabbitConfig;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* 消息的消费者
* 监听'direct_queue'队列
*/
@Component
public class Receiver {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RabbitListener(queues = RabbitConfig.DIRECT_QUEUE)
public void directReceive(Message message, Channel channel) throws IOException {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
logger.info("direct_queue: " + new String(message.getBody()));
}
}
6.代码测试
package com.example.mq.controller;
import com.example.mq.sender.Sender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/mq")
@RestController
public class testController {
@Autowired
private Sender sender;
@GetMapping("/test")
public void testMq(String message){
sender.sendMsg(message);
}
}