![](/img/trans.png)
[英]Spring Kafka: Multiple Listeners for different objects within an ApplicationContext
[英]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.