Общие типы KafkaConsumer для avro SpecificRecord с использованием отражения

#java #reflection #apache-kafka #avro

#java #отражение #apache-kafka #avro

Вопрос:

Я хочу инициализировать KafkaConsumer универсальные типы, используя классы, загруженные отражением. Классы будут сгенерированы с помощью avro-tools и будут расширять SpecificRecordBase class . Я знаю, я могу использовать подстановочные знаки и делать что-то вроде —

 KafkaConsumer<? extends SpecificRecordBase, ? extends SpecificRecordBase> consumer = new KafkaConsumer<>(properties);
 

Тем не менее, я ищу что-то вроде —

 Class keyClass = Class.forName("com.test.KeyClass");
Class valueClass = Class.forName("com.test.ValueClass");
KafkaConsumer<keyClass, valueClass> consumer = new KafkaConsumer<>(properties);
 

Любые указатели будут оценены. Спасибо.

Комментарии:

1. Это невозможно и не полезно.

Ответ №1:

Поскольку параметры типа существуют только для удобства программистов, во время выполнения они будут удалены, поэтому нет смысла загружать их с помощью reflection.

Однако вы можете привести его к нужному типу, например

 Consumer<KeyClass, ValueClass> consumer = new KafkaConsumer<>(properties);
 

Ответ №2:

Я не уверен, но если приведенных ниже требований достаточно —

 public Consumer<?,?> getConsumer(Class<?> keyClass,Class<?> valClass,
                                   Properties props){
    props.put(deserializer properties of keyClass);
    props.put(deserializer properties of valClass);
   //other releavant props 
   return new KafkaConsumer<>(props);
}
  ..
   caller(){
   Class<?> keyClass=Class.forName("KeyClass");
   Class<?> valClass=Class.forName("ValClass");
   KafkaConsumer<?,?> con=(KafkaConsumer<?,?>)getConsumer(keyClass,valClass,props);
} 
 

Ответ №3:

Настройте отдельную задачу для сборки и публикации jar схемы (я бы рекомендовал поместить их в отдельный репозиторий с собственной сборкой). Затем вставьте зависимость через Gradle / Maven, у вас будут фактические типы, и отражение не должно быть необходимым.