在springboot项目中引入RabbitMq导致报循环依赖错误
报错信息
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| myRabbitConfig
↑ ↓
| rabbitTemplate defined in class path resource [org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration$RabbitTemplateConfiguration.class]
↑ ↓
| rabbitTemplateConfigurer defined in class path resource [org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration$RabbitTemplateConfiguration.class]
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Process finished with exit code 1
明显就是循环依赖问题,然后我就去网上搜,大概就是我自己写的配置类引发的这个问题,不能将这个rabbitTemplate自动注入要我们手动注入,并且@PostConstruct这个注解也导致这个问题
解决方法:
删除@Resource注解
自己注入rabbitTemplate
去掉@PostConstruct注解就好了
自定义注入
@Primary
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setMessageConverter(messageConverter());
initRabbitTemplate();
return rabbitTemplate;
}
完整代码
@Configuration
public class MyRabbitConfig {
// @Resource
RabbitTemplate rabbitTemplate;
/**
* 使用JSON序列化机制,进行消息转换
* @return
*/
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
@Primary
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setMessageConverter(messageConverter());
initRabbitTemplate();
return rabbitTemplate;
}
/**
* 定制RabbitTemplate
* 1、服务器收到消息就回调
* 1、publisher-confirm-type: correlated
* 2、设置确认回调ConfirmCallback
* 2、消息正确抵达队列进行回调
* 1、#开启发送端消息抵达队列确认
* publisher-returns: true
* template:
* mandatory: true #只要抵达队列,以异步模式优先回调我们这个returnConfirm
* 2、设置确认回调
* 3、消费端(保证每一个消息被正确消费,此时才可以broken删除这个消息)
* 1、默认是自动确认的,只要消息接收到,客户端会自动确认
*/
@PostConstruct //MyRabbitConfig对象创建完以后,调用这个方法
public void initRabbitTemplate(){
//设置确认回调
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
/**
*
* @param correlationData 当前消息的唯一关联数据(这个消息的唯一id)
* @param b 消息是否成功收到
* @param s 失败的原因
*/
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
System.out.println("confirm...correlationData:"+correlationData+"ack:==="+b+"s====>"+s);
}
});
//设置消息抵达队列的确认回调
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
/**
* 只要消息没有投递给指定队列,就触发这个失败回调
* @param returnedMessage
*/
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
//投递失败的消息,详细信息
Message message = returnedMessage.getMessage();
//回复的状态码
int replyCode = returnedMessage.getReplyCode();
//回复的文本内容
String replyText = returnedMessage.getReplyText();
// 当时这个消息发给哪个交换机
String exchange = returnedMessage.getExchange();
//当时这个消息用哪个路由键
String routingKey = returnedMessage.getRoutingKey();
System.out.println("message====>"+message+"replyCode====>"+replyCode+"replyText=====>"
+replyText+"exchange=====>"+exchange+ "routingKey====>"+routingKey);
}
});
}
}