SpringBoot Kafka: метод компонента 'kafkaTemplate' в 'KafkaAutoConfiguration' не загружен

Я использую springboot и пытаюсь написать KafkaProducer для отправки сообщений в очередь Kafka. Я создал эти методы в классе @Configuration.

@Bean
public KafkaTemplate<String, String> kafkaTemplate(){
    return new KafkaTemplate<>(producerFactory());
}

@Bean
public ProducerFactory<String, String> producerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); //bootstrapAddress holds address of kafka server
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    return new DefaultKafkaProducerFactory<>(configProps);
}

И я автоматически подключил этот bean-компонент KafkaTemplate в моем классе KafkaMessageProducer, который заботится об обработке функции отправки KafkaTemplate.

@Autowired
KafkaTemplate<String, String> kafkaTemplate;

Но я сталкиваюсь с этой ошибкой, когда пытаюсь скомпилировать свой код.

Field kafkaTemplate in <pathoffile>.KafkaMessageProducer required a bean of type 'org.springframework.kafka.core.KafkaTemplate' that could not be found.
    - Bean method 'kafkaTemplate' in 'KafkaAutoConfiguration' not loaded because @ConditionalOnMissingBean (types: org.springframework.kafka.core.KafkaTemplate; SearchStrategy: all) found bean 'avroKafkaTemplate'
Action:Consider revisiting the conditions above or defining a bean of type 'org.springframework.kafka.core.KafkaTemplate' in your configuration.

Кроме того, если я попытаюсь исключить KafkaAutoConfiguration в моем проекте Spring, я получаю сообщение об ошибке «Не удается загрузить Bean, поскольку KafkaAutoConfiguration отключен». Есть идеи, почему я получаю эту ошибку Bean и какое решение?

РЕДАКТИРОВАТЬ: - Я нашел следующий bean в файле jar, используемом моим проектом

@Bean
@Conditional({EnableQueueCondition.class})
public KafkaTemplate<String, String> kafkaTemplate() {
    KafkaTemplate<String, String> kafkaTemplate = new KafkaTemplate(this.producerFactory());
    kafkaTemplate.setProducerListener(new ProducerListenerImpl());
    return kafkaTemplate;
}

Итак, здесь возникает ошибка, но я не знаю, как сказать Spring не смотреть на этот bean-компонент и использовать bean-компонент, который я определил. Я пробовал использовать аннотации Primary и Qualifier для bean-компонента, но по-прежнему выдает ту же ошибку. Может ли быть вероятность того, что мой определенный bean-компонент не создан или не найден, и KafkaAutoConfiguration затем ищет bean-компонент по умолчанию, который переопределяется bean-компонентом avroKafkaTemplate? Какое может быть решение этой проблемы?


person Vishal Rastogi    schedule 09.09.2020    source источник


Ответы (2)


Из трассировки стека есть еще один KafkaTemplate bean - avroKafkaTemplate. Итак, я предполагаю, что есть другая конфигурация, дублирующая определение KafkaTemplate.

person Mikalai Lushchytski    schedule 09.09.2020
comment
да, возможно, но я не уверен. Как вы думаете, как я могу решить эту проблему? - person Vishal Rastogi; 09.09.2020
comment
У вас есть какая-нибудь конфигурация с avroKafkaTemplate() методом? Это определенно настраиваемый компонент. - person Mikalai Lushchytski; 09.09.2020
comment
Кодовая база, над которой я работаю, довольно большая, но даже при поиске по ней я не нахожу совпадений с avroKafkaTemplate - person Vishal Rastogi; 09.09.2020
comment
Есть ли у вас какие-либо зависимости, обеспечивающие собственную конфигурацию? Как и другой подмодуль, у которого также есть компонент конфигурации? - person Mikalai Lushchytski; 09.09.2020
comment
Да, их очень много. - person Vishal Rastogi; 09.09.2020
comment
Итак, вероятно, один из них определяет avroKafkaTemplate bean - person Mikalai Lushchytski; 09.09.2020
comment
Не могли бы вы добавить квалификатор @Primary к определению KafkaTemplate bean-компонента? - person Mikalai Lushchytski; 09.09.2020
comment
Да, я пробовал это, а также @Qualifier, но все та же ошибка. Кроме того, я нашел Bean с avroKafkaTemplate в jar-файле, который использует мой проект, поэтому Spring получает этот bean-компонент. Но я думаю, что avroKafkaTemplate ищется только тогда, когда bean-компонент KafkaTemplate (который определен мной) не найден, а bean-компонент по умолчанию не возвращается из-за этого bean-компонента avroKafka. Как вы думаете, что мы можем сделать в этом сценарии? - person Vishal Rastogi; 09.09.2020
comment
Ваш @Configuration класс правильно определен и загружен? не могли бы вы подтвердить, что определение вашего KafkaTemplate bean-компонента действительно загружено? Например, печать на консоли внутри метода. - person Mikalai Lushchytski; 09.09.2020

По умолчанию весенняя загрузка предоставляет bean-компонент KafkaTemplate, если вы добавляете зависимость kafka в POM.

Вам просто нужно определить свойства в вашем примере файла application.yml:

server: port: 9000
spring:
   kafka:
     consumer:
        bootstrap-servers: localhost:9092
        group-id: group_id
        auto-offset-reset: earliest
        key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
        value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
     producer:
        bootstrap-servers: localhost:9092
        key-serializer: org.apache.kafka.common.serialization.StringSerializer
        value-serializer: org.apache.kafka.common.serialization.StringSerializer

включить автоконфигурацию

@Configuration
@EnableKafka

и автоматически подключите kafkaTemplate:

 @Autowired
 private KafkaTemplate<String, String> kafkaTemplate;

Если в вашем случае завод автоконфигурации ищет ProducerFactory<String, Strng>, который не соответствует вашей конфигурации.

 @Bean
 @ConditionalOnMissingBean(ProducerFactory.class)
        public ProducerFactory<String, Strng> kafkaProducerFactory()

поэтому переименуйте свой ProducerFactory () в kafkaProducerFactory (), это решит вашу проблему.

person Imran Ahmad    schedule 09.09.2020
comment
Имран, переименование производителяFactory () в kafkaProducerFactory () не сработало, по-прежнему отображается та же ошибка. Зависимость добавлена ​​в файл POM. - person Vishal Rastogi; 09.09.2020
comment
В моем коде он работает .... Я только что определил свой bean-компонент следующим образом: @Bean public KafkaTemplate kafkaTemplate (ProducerFactory ‹String, String› pf) {return new KafkaTemplate (pf); } Также не забудьте использовать EnableAutoConfiguration - person Imran Ahmad; 09.09.2020
comment
Да, он включен, я обновил вопрос, добавив некоторые дополнительные сведения, пожалуйста, посмотрите, может ли это помочь в поиске решения. - person Vishal Rastogi; 09.09.2020
comment
Если этот компонент не требуется в вашем проекте, вы можете исключить определенные классы из сканирования в компоненты с помощью параметра excludeFilters аннотации @ComponentScan. Пример: @ComponentScan (value = {'com.xyz.abc'}, excludeFilters = {@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, classes = {firstClass.class, secondClass.class})}) - person Imran Ahmad; 09.09.2020