Why doesn’t Spring create a Bean even tho it has a @Component annotation?

This question has been asked many times i guess but i don’t find the solution to my problem from these threads.

I’m getting this error and i cannot explain why.


APPLICATION FAILED TO START


Description:

Parameter 0 of method listenerAdapter in com.ll.rabbittutorial.messagingconsumer.MessagingconsumerApplication required a bean of type ‘com.ll.rabbittutorial.messagingconsumer.RoomCleanerProcessor’ that could not be found.

Action:

Consider defining a bean of type ‘com.ll.rabbittutorial.messagingconsumer.RoomCleanerProcessor’ in your configuration.

This is the class that i guess is responsible for the error

@Component
public class RoomCleanerProcessor {


    private final ObjectMapper objectMapper;

    private static final Logger logger = LoggerFactory.getLogger(RoomCleanerProcessor.class);

    @Autowired
    public RoomCleanerProcessor(ObjectMapper objectMapper)
    {
        super();
        this.objectMapper=objectMapper;
    }

    public void receiveMessage(String roomJson){
        logger.info("Message received");
        try{
            Room room = this.objectMapper.readValue(roomJson, Room.class);
            logger.info("Room ready for cleaning "+room.getNumber());
        } catch (IOException e) {
            logger.error("Exception caught", e);

        }
    }
}

First the same error was at the ObjectMapper object that i tried to inject. but after using the @ComponentScan annotation at the application class, the problem disappeared.

@SpringBootApplication
@ComponentScan({"com.ll.rabbittutorial.messagingconsumer.RoomCleanerProcessor"})
public class MessagingconsumerApplication {

    @Value("$amqp.queue.name}")
    private String queueName;

    @Value("${amqp.exchange.name}")
    private String exchangeName;

    @Bean
    public Queue queue(){
        return new Queue(queueName, false);
    }

    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(exchangeName);
    }

    @Bean
    public Binding binding(Queue queue, TopicExchange topicExchange){
        return BindingBuilder.bind(queue).to(topicExchange).with(queueName);
    }

    @Bean
    public MessageListenerAdapter listenerAdapter(RoomCleanerProcessor roomCleanerProcessor){
        return new MessageListenerAdapter(roomCleanerProcessor, "receiveMessage");

    }
    @Bean
    public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(queueName);
        container.setMessageListener(listenerAdapter);
        return container;
    }

    public static void main(String[] args) {
        SpringApplication.run(MessagingconsumerApplication.class, args);
    }

}

I thought i can fix this problem by also componentscaning the applicationclass but it didnt’t help. How do i fix this?

Answer

@ComponentScan value is supposed to include packages, not classes. Additionally, @SpringBootApplication encapsulates @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations with their default attributes.

The default for @ComponentScan is no arguments. Without arguments, it tells Spring to scan the current package and all of its sub-packages. So if you place MessagingconsumerApplication in a parent package of RoomCleanerProcessor it should work.