简体   繁体   中英

Cannot autowire bean in MessageListener Class AMQP

Ok. So i have a rabbit configuration class with some constants and I try to add a service to my listenercontainer listener.

@Configuration
public class RabbitConfig {

@Bean
public ConnectionFactory connectionFactory() {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory(HOST);
    connectionFactory.setPort(CONN_PORT);
    connectionFactory.setUsername(USERNAME);
    connectionFactory.setPassword(PASSWORD);
    return connectionFactory;
}

@Bean
public AmqpAdmin amqpAdmin() {
    return new RabbitAdmin(connectionFactory());
}

@Bean
public RabbitTemplate rabbitTemplate() {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
    rabbitTemplate.setReplyQueue(replyQueue());
    rabbitTemplate.setCorrelationKey(UUID.randomUUID().toString());
    return rabbitTemplate;
}

@Bean
public Queue replyQueue() {
    return new Queue(REPLY_QUEUE_NAME);
}

@Bean
public SimpleMessageListenerContainer messageListenerContainer() {

    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
    container.setQueueNames(QUEUE_NAME);
    container.setMessageListener(messageListener());
    return container;
}

@Bean
public MessageListener messageListener(){
    return new RabbitListener();
}

}

I am trying to inject into the messagelistener which is created in the last lines a service from my project. This triggers an error of cannot autowire field as if the field is not managed by Spring. I did some research and I verified my component scan package and it's set to all the project, I have annotated the rabbitlistener with @Component so I can't really find the mistake or why Spring cannot autowire the field in my listener class. Here is the code.

@Component
public class RabbitListener implements MessageListener {
Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
ImagesService imagesService;


@Override
public void onMessage(Message message) {
//processing message
}

Any ideas please?

Would be better if you'd share the full StackTrace, but I suggest you do something like this:

  1. Add @ComponentScan for your @Configuration class and specify there those packages where are your RabbitListener and ImagesService classes

  2. Mark the last two with @Component (Yes, I see that on your RabbitListener , but it isn't clear where your ImagesService and how it is going around it)

  3. Than @Autowire RabbitListener to that RabbitConfig instead of @Bean for it.

And be careful with the @Component and @Bean mix: you end up with two bean, if you have @ComponentScan for that package, of course.

Okay, u need to @Autowire the RabbitListener bean. Since the RabbitListener is a bean that need to be managed by the IOC, since is declared @Component , hence @runtime the RabbitListener is not in the context, hence autowire it in the config class like so

@Configuration
public class RabbitConfig {

@Bean
public ConnectionFactory connectionFactory() {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory(HOST);
    connectionFactory.setPort(CONN_PORT);
    connectionFactory.setUsername(USERNAME);
    connectionFactory.setPassword(PASSWORD);
    return connectionFactory;
}

@Bean
public AmqpAdmin amqpAdmin() {
    return new RabbitAdmin(connectionFactory());
}

@Bean
public RabbitTemplate rabbitTemplate() {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
    rabbitTemplate.setReplyQueue(replyQueue());
    rabbitTemplate.setCorrelationKey(UUID.randomUUID().toString());
    return rabbitTemplate;
}

@Bean
public Queue replyQueue() {
    return new Queue(REPLY_QUEUE_NAME);
}

@Bean
public SimpleMessageListenerContainer messageListenerContainer() {

    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
    container.setQueueNames(QUEUE_NAME);
    container.setMessageListener(rabbitListener); // reference the autowired RabbitListener on this line
    return container;
}

@Autowire
private RabbitListener rabbitListener;
}

That should resolve this error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM