簡體   English   中英

Java Spring Kafka:多個監聽器

[英]Java Spring Kafka: multiple listeners

目前正在嘗試讓同一項目中的兩個不同的聽眾使用。 在其他各種帖子之后都會產生不同的錯誤,但總的來說似乎沒有正確定義 bean。

KafkaConsumerConfig(管道消息)



@EnableKafka
@Configuration
public class KafkaConsumerConfigPipelineMessage {
    @Value(value = "${spring.kafka.bootstrap-servers}")
    private String bootstrapAddress;

    @Value(value = "${spring.kafka.producer.group-id}")
    private String groupId;

    @Value(value = "${saslMechanism}")
    private String saslMechanism;

    @Value(value = "${kafkaUser}")
    private String kafkaUser;

    @Value(value = "${kafkaPassword}")
    private String kafkaPassword;

    @Value(value = "${securityProtocol}")
    private String securityProtocol;
    @Bean
    public ConsumerFactory<String, PipelineMessage> consumerFactory() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, AvroDeserializer.class);
        props.put("sasl.mechanism",saslMechanism);
        props.put("security.protocol",securityProtocol);
        props.put("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule required username ='"+kafkaUser+"' password = '"+kafkaPassword+"';");
        return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new AvroDeserializer<>(PipelineMessage.class));
    }

    @Bean("kafkaListenerPipelineMessage")
    public ConcurrentKafkaListenerContainerFactory<String, PipelineMessage> kafkaListenerContainerFactory() {

        ConcurrentKafkaListenerContainerFactory<String, PipelineMessage> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}

KafkaConsumerConfig(橋)

@EnableKafka
@Configuration
public class KafkaConsumerConfigBridge {

    @Value(value = "${spring.kafka.bootstrap-servers}")
    private String bootstrapAddress;

    @Value(value = "${spring.kafka.producer.group-id}")
    private String groupId;

    @Value(value = "${saslMechanism}")
    private String saslMechanism;

    @Value(value = "${kafkaUser}")
    private String kafkaUser;

    @Value(value = "${kafkaPassword}")
    private String kafkaPassword;

    @Value(value = "${securityProtocol}")
    private String securityProtocol;

    @Bean
    public ConsumerFactory<String, Bridge> consumerFactory() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, AvroDeserializer.class);
        props.put("sasl.mechanism",saslMechanism);
        props.put("security.protocol",securityProtocol);
        props.put("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule required username ='"+kafkaUser+"' password = '"+kafkaPassword+"';");
        return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new AvroDeserializer<>(Bridge.class));
    }

    @Bean("kafkaListenerBridge")
    public ConcurrentKafkaListenerContainerFactory<String, Bridge> kafkaListenerContainerFactory() {

        ConcurrentKafkaListenerContainerFactory<String, Bridge> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}

聽眾

 @KafkaListener(id = "id1",topics = "${kafka.topic.consumer.name.rb}", groupId = "${spring.kafka.producer.group-id}", containerFactory = "kafkaListenerBridge")
    public void consumeBridgeForPayroll(Bridge message) throws IOException {

@KafkaListener(id = "id2",topics = "${kafka.topic.consumer.name.dlq}",groupId = "${spring.kafka.consumer.group-id}", containerFactory = "kafkaListenerPipelineMessage")
    public void consumeForMessages(PipelineMessage message) throws 

我嘗試將 Bean 名稱移動到 consumerFactory function 但這沒有幫助。 對於當前的實現,錯誤表明偵聽器 bean 的類型錯誤。

更改 consumerFactory 的名稱后,出現以下錯誤。

"timestamp":"2021-09-27T22:02:11.273Z","level":"ERROR","thread":"main","logger":"org.springframework.boot.SpringApplication","message":"Application run failed","context":"default","exception":"org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'kafkaListenerContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/kafka/KafkaAnnotationDrivenConfiguration.class]: Unsatisfied dependency expressed through method 'kafkaListenerContainerFactory' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.kafka.core.ConsumerFactory<java.lang.Object, java.lang.Object>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:847)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at com.employbridge.core.timecollectionservice.Application.main(Application.java:15)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.kafka.core.ConsumerFactory<java.lang.Object, java.lang.Object>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1662)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1221)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
... 19 common frames omitted
"

你有兩個同名的豆子:

@Bean
public ConsumerFactory<String, PipelineMessage> consumerFactory() {

@Bean
public ConsumerFactory<String, Bridge> consumerFactory() {

哪個互相覆蓋。 好吧,他們中的一個最終會獲勝。

即使您認為您在同一個 class 中調用了consumerFactory()方法,它仍然會委托BeanFactory返回一個 bean。 這可能來自不同的定義。 解決這個問題的最佳方法是讓這些ConsumerFactory具有不同的名稱。 只需更改方法名稱即可:它默認用於 bean 名稱定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM