Spring boot 如何有效地将@KafkaListener绑定到ConcurrentKafkaListenerContainerFactory?

Spring boot 如何有效地将@KafkaListener绑定到ConcurrentKafkaListenerContainerFactory?,spring-boot,apache-kafka,spring-kafka,Spring Boot,Apache Kafka,Spring Kafka,我遇到了一个我觉得很奇怪的场景: 基本上我在一个类中定义了两个@KafkaListener: @KafkaListenerid=listener1,idIsGroup=false,topics=data1,containerFactory=kafkaListenerContainerFactory 公共无效接收{} @KafkaListenerid=listener2,idIsGroup=false,topics=data2,containerFactory=kafkaListenerConta

我遇到了一个我觉得很奇怪的场景:

基本上我在一个类中定义了两个@KafkaListener:

@KafkaListenerid=listener1,idIsGroup=false,topics=data1,containerFactory=kafkaListenerContainerFactory 公共无效接收{} @KafkaListenerid=listener2,idIsGroup=false,topics=data2,containerFactory=kafkaListenerContainerFactory2 公共无效接收{} 它们的id、主题、containerFactory各不相同,并且它们都依赖于另一个类中定义的不同ConcurrentKafkListenerContainerFactory:

@豆子 公共并发kafkaListenerContainerFactory kafkaListenerContainerFactory{ ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory; factory.setConsumerFactoryconsumerFactorygroup1,最早; factory.setAutoStartupfalse; 返回工厂; } @豆子 公共并发KafkalistenerContainerFactory kafkaListenerContainerFactory2{ ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory; factory.setConsumerFactoryconsumerFactorygroup2,最新版本; factory.setAutoStart; 返回工厂; } @豆子 公共ConsumerFactory consumerFactoryString组ID,字符串偏移量{ Map config=新的HashMap; //dt是以毫秒为单位的当前时间戳 config.putcummerconfig.GROUP_ID_config,groupId+-+dt; config.putcummerconfig.AUTO\u OFFSET\u RESET\u配置,OFFSET; //省略其他配置 返回新的DefaultKafkanConsumerFactoryConfig; } 因此,我期望看到和想要实现的是:

只有listener2将自动启动,因为 factory.SetAutoStart实用程序 Listener2将以group.id group2和auto.offset.reset latest开头 稍后,当listener1通过某个事件侦听器启动时,它将启动 使用group.id group1和auto.offset.reset earlist 然而,实际上只有第一个是有保证的。Listener2可以以{group2+最新}或{group1+最早}开头。稍后,当listener1开始使用数据时,它只会重用listener2的配置。我可以看到包含时间戳的相同组id在我的日志中打印了两次

我的问题是,为什么listener2的组ID和偏移量配置是随机选择的,而AutoStart不是?为什么listener1会重用listener2的配置?

这是因为consumerFactory是一个singleton@Bean,第二次调用时会忽略参数

将@ScopeConfigurableBeanFactory.SCOPE\u原型添加到工厂,每次获得一个新的bean

但是,您不需要这些,只需在注释上设置groupId属性,就可以避免所有这些额外的定义

从2.2开始,您还可以在注释上控制自动启动

编辑

要回答下面评论中的问题

groupId = "#{'${group.id}' + T(java.time.Instant).now().toEpochMilli()}"
但是,如果需要唯一的组id;这是更可靠的

groupId = "#{'${group.id}' + T(java.util.UUID).randomUUID()}"

谢谢你,加里!添加@ScopeConfigurableBeanFactory.SCOPE\u原型效果良好。如果我想将其保持为单例,有没有办法用注释上的当前时间戳设置groupId?比如@KafkaListenerid=${topic},groupId=${group.id}+Instant.now.toEpochMilli?这条线不行,加里!正如我自己和人们在将来遇到这个问题时要注意的一样,SpEL的这个用例在第6.4节和第6.4节中有很好的文档记录。可能没有太大的变化,但是SpEL文档链接是非常古老的Spring3.0。当前的SpEL文档是。