【问题标题】:SpringBoot Kafka: Bean method 'kafkaTemplate' in 'KafkaAutoConfiguration' is not loadedSpringBoot Kafka:“KafkaAutoConfiguration”中的 Bean 方法“kafkaTemplate”未加载
【发布时间】:2020-09-10 00:45:13
【问题描述】:

我正在使用 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);
}

我已经在我的 KafkaMessageProducer 类中自动装配了这个 KafkaTemplate bean,它负责处理 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.

另外,如果我尝试在我的 Spring 项目中排除 KafkaAutoConfiguration,我会收到类似“无法加载 Bean,因为 KafkaAutoConfiguration 已禁用”的错误。 知道为什么我会收到此 Bean 错误以及可能的解决方案吗?

编辑:- 我在我的项目使用的 jar 文件中发现了以下 bean

@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。我尝试在 bean 上使用 Primary 和 Qualifier 注释,它仍然给出相同的错误。是否有可能未创建或找不到我定义的 bean,然后 KafkaAutoConfiguration 正在寻找被 avroKafkaTemplate bean 覆盖的默认 bean?有什么办法可以解决这个问题?

【问题讨论】:

    标签: spring spring-boot spring-mvc apache-kafka spring-kafka


    【解决方案1】:

    从堆栈跟踪中,还有另一个 KafkaTemplate bean - avroKafkaTemplate。所以我猜还有另一种配置,复制KafkaTemplate的定义。

    【讨论】:

    • 是的,但我不确定。你觉得我该如何解决这个问题?
    • 你有avroKafkaTemplate()方法的配置吗?这绝对是一个自定义的 bean。
    • 我正在使用的代码库非常大,但即使在搜索它时,我也找不到与 avroKafkaTemplate 匹配的任何匹配项
    • 您是否有任何依赖项提供自己的配置?像其他子模块一样,它也有一个配置bean?
    • 是的,有很多。
    【解决方案2】:

    如果你在 POM 中添加 kafka 依赖,spring boot 默认会提供 KafkaTemplate bean。

    您只需要在 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&lt;String, Strng&gt;

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

    所以将你的 producerFactory() 重命名为 kafkaProducerFactory(),它将解决你的问题。

    【讨论】:

    • Imran,将 producerFactory() 重命名为 kafkaProducerFactory() 不起作用,它仍然显示相同的错误。在 POM 文件中添加依赖。
    • 在我的代码中它正在工作......我只是这样定义了我的 bean:@Bean public KafkaTemplate kafkaTemplate(ProducerFactory pf) { return new KafkaTemplate(pf);还要确保使用 EnableAutoConfiguration
    • 是的,它已启用,我用一些额外的细节更新了问题,请看看它是否有助于找到解决方案。
    • 如果您的项目中不需要该 bean,那么您可以使用 @ComponentScan 注释的 excludeFilters 参数排除特定类被扫描到 bean 中。例如:@ComponentScan(value = {'com.xyz.abc'}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = { firstClass.class, secondClass.class }) })
    猜你喜欢
    • 2020-06-28
    • 2020-02-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多