Sam Bellekens
Sam Bellekens

Reputation: 93

How do i configure two rabbitlisteners differently in the same project?

I have two queues and they each have messages on them. Queue one has bird objects and queue two has birdspotting object. I'm using a defaultclassmapper to convert the messages back into objects. Is there a way for me to add different configurations on both my rabbitlisteners.

My listeners.

 @Qualifier("bird")
@RabbitListener(queues = "vogels")
public void receiveBird(Bird in)  
    BirdSpotting birdSpotting = new BirdSpotting();
    birdSpotting.setBird(in);
    rabbitTemplate.convertAndSend("vogelspottings",birdSpotting);
}

@Qualifier("birdspotting")
@RabbitListener(queues = "vogelspottingmetlocatie")
public void receiveBirdWithLocation(BirdSpotting birdSpotting){
    service.saveBirdSpotting(birdSpotting);

}

My configuration class.

@Configuration
@EnableRabbit
public class RabbitConf2 implements RabbitListenerConfigurer {
    @Autowired
    DefaultClassMapper mapper;


    @Bean
    public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
        return new MappingJackson2MessageConverter();
    }

    @Bean
    public DefaultMessageHandlerMethodFactory messageHandlerMethodFactory() {
        DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
        factory.setMessageConverter(consumerJackson2MessageConverter());
        return factory;
    }


    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
        registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
    }

    @Bean
    public RabbitTemplate rabbitTemplateService2(final ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(producerJackson2MessageConverterService2());
        return rabbitTemplate;
    }

    @Bean
    public Jackson2JsonMessageConverter producerJackson2MessageConverterService2() {
        final Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        jackson2JsonMessageConverter.setClassMapper(mapper);

        return jackson2JsonMessageConverter;
    }

My two defaultclassmappers for both queues:

@Bean(value = "bird")
    public DefaultClassMapper classMapperService2() {
        DefaultClassMapper classMapper = new DefaultClassMapper();
        Map<String, Class<?>> idClassMapping = new HashMap<>();
        idClassMapping.put("be.kdg.birdgeneratorservice.Bird", Bird.class);
        classMapper.setIdClassMapping(idClassMapping);
        return classMapper;
    }

    @Bean(value = "birdspotting")
    public DefaultClassMapper classMapperService3() {
        DefaultClassMapper classMapper = new DefaultClassMapper();
        Map<String, Class<?>> idClassMapping = new HashMap<>();
        idClassMapping.put("be.kdg.locationservice.BirdSpotting", BirdSpotting.class);
        classMapper.setIdClassMapping(idClassMapping);
        return classMapper;
    }

Upvotes: 1

Views: 2382

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121550

You need to introduce one more RabbitListenerContainerFactory bean with an appropriate configuration and use its name from the second @RabbitListener:

/**
 * The bean name of the {@link org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory}
 * to use to create the message listener container responsible to serve this endpoint.
 * <p>If not specified, the default container factory is used, if any.
 * @return the {@link org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory}
 * bean name.
 */
String containerFactory() default "";

This way you will distinguish a default one provided by the Spring Boot and will have your own custom for another use-case.

See more info in the Docs: https://docs.spring.io/spring-amqp/docs/2.1.4.RELEASE/reference/#async-annotation-driven

Upvotes: 1

Related Questions