Replacing micronaut's default KafkaProducerFactory with custom factory implementation

291 Views Asked by At

I need to customize the default KafkaProducerFactory (or any other default factory, say KafkaConsumerFactory) that ships with micronaut-kafka dependency. For that I tried to replace the existing factory using,

@Factory
@Replaces(factory = KafkaProducerFactory.class)
class CustomFactory extends KafkaProducerFactory {
  
  @Bean
  @Any
  public <K, V> Producer<K, V> getProducer(
        @Nullable InjectionPoint<KafkaProducer<K, V>> injectionPoint,
        @Nullable @Parameter AbstractKafkaProducerConfiguration<K, V> producerConfiguration) {

     validate(producerConfiguration); //this is my primary intension
     super.getProducer(injectionPoint, producerConfiguration);
  }
}

But it seems that Micronaut is not able to replace KafkaProducerFactory hence both the factory exists and I am getting error saying

"multiple candidate bean exists [CustomFactory, KafkaProducerFactory]"

I also thought to exclude the KafkaProducerFactory while the application loads, but could not find anything similar to Spring's ComponentScan.excludeFilter in Micronaut.

Is there anything wrong in my configuration or is there any other way to achieve the same?

1

There are 1 best solutions below

0
On BEST ANSWER

Finally I got the answer. Let me elaborate little more for the actual context,

Problem

We have custom way of creating producer/consumer instances i.e. a custom class that creates those given the config properties. Now I had to modify the default factories so that instead of creating the instances on its own, the factory should invoke our custom class to instantiate producer/consumers.

Solution

I had to add @Primary along with other annotations and its working,

@Factory
@Replaces(factory = KafkaProducerFactory.class)
@Primary
class CustomFactory extends KafkaProducerFactory {
   //code here
}

But the way I acheived this is kind of a work around because,

my primary intension was to override the producer/consumer creation part of default factory in a sub class and then replacing the default factory by the sub class. But as per the code structure in default factory class, it was not a single place where we can plug our custom code (no specific public method present consolidating the code for creating producer/consumer, it was being created from 3 separate places with "new") to create the producer. Hence we had to copy the entire default factory class and replaced the 3 places with custom code which does not seem to be a correct way.