Sayed Uz Zaman
Sayed Uz Zaman

Reputation: 656

RabbitMQ @RabbitListener annotation not working in Spring (not spring-boot)

I am trying to implement rabbitmq in my spring-core developed application. Below is my pom.xml

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-amqp</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>2.2.7.RELEASE</version>
        </dependency>

This is my RabbitConfiguration java file



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.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
public class RabbitConfiguration {
    public static final String QUEUE_NAME="MyQueue";
    public static final String EXCHANGE_NAME="My_EXCHANGE";


    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory =
                new CachingConnectionFactory("localhost");
        return connectionFactory;
    }

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

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public Queue myQueue() {
        return new Queue(QUEUE_NAME,false);
    }


   @Bean
   MessageListenerContainer messageListenerContainer() {
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setConnectionFactory(connectionFactory());
        simpleMessageListenerContainer.setQueues(myQueue());
        simpleMessageListenerContainer.setMessageListener(new RabbitMQListner());
        return simpleMessageListenerContainer;
    }
    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

}

And here is my service class from where I am trying to use the rabbit

import com.rabbitmq.client.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.IOException;
@Component
public class MessagingService{
    public void send(String msg){
        template.convertAndSend(QUEUE_NAME,msg);
    }


    @RabbitListener(queues = "foo")
    public void receiveMessage(String car)
    {
        System.out.println("Hello"+car);
    }
    @Bean
    private ApplicationContext context(){
        return new AnnotationConfigApplicationContext(RabbitConfiguration.class);
    }

    @Bean
    private AmqpTemplate amqpTemplate(){
        return context().getBean(AmqpTemplate.class);
    }

    @Autowired
    protected AmqpTemplate template;

The send method works just fine. But the @Listener annotated method does not work. It does not listen. What I also tried, I created another config file and annotated with @EnableRabbit, but no benefits. Is there any secret sausage to make it working?

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@EnableRabbit
@Configuration
public class AppConfig extends RabbitConfiguration {
    @Bean
    public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        factory.setMaxConcurrentConsumers(5);
        factory.setMessageConverter(jsonMessageConverter());
        return factory;
    }
}

Upvotes: 1

Views: 5148

Answers (2)

ejaenv
ejaenv

Reputation: 2387

It could be that the code is creating its own container factory, myRabbitListenerContainerFactory, but @RabbitListener by default listens to rabbitListenerContainerFactory.

Try with @RabbitListener(queues = "foo", connectionFactory="myRabbitListenerContainerFactory")

Ref: https://docs.spring.io/spring-amqp/api/org/springframework/amqp/rabbit/annotation/RabbitListener.html

Upvotes: 0

Guru prasath
Guru prasath

Reputation: 23

i hope you already resolved this issue, here is what i think if its not resolved. You don't need to use SimpleRabbitListenerContainerFactory or SimpleMessageListenerContainer class when you use @RabbitListener. in SimpleMessageListenerContainer config class you mapped RabbitMQListner class for listening but you are trying to listen msg in MessagingService class. in SimpleRabbitListenerContainerFactory you hvnt set the messagelistener itself.

Upvotes: 1

Related Questions