在不受 Spring 管理的 class 中使用 KafkaListener

Use KafkaListener in class not managed by Spring

在我的项目中,我有很多 spring 托管组件做同样的事情。我想创建一个通用 Util class 来为我的所有组件执行所有通用操作。由于此 Util class 需要访问环境变量和 bean,因此它的实例化如下:

// Util class:
public class FooUtil {
    public FooUtil(Environment env) {
        env.getProperty("FOO_TOPIC", "foo")
    }
}

// Example configuration for one of my components:
@Configuration
public class ComponentConfig {
    @Bean
    FooUtil fooUtil(Environment env) {
        return new FooUtil(env);
    }
}

这允许 FooUtil 访问所有环境变量和 bean,而无需本身是组件。

现在,这个Utilclass还需要监听kafka主题。每个组件当前都有一个侦听器设置如下:

@KafkaListener(topics = "${FOO"_TOPIC:foo2}", containerFactory = "kafkaListenerContainerFactory")
private void fooListener(ConsumerRecord<String, Foo> rec) {
    // Stuff...
}

我想把这个kafka监听器移到FooUtil中。我该怎么做? 明确地说,我希望 FooUtil 在组件实例化和初始化后立即开始侦听。

由于 FooUtil 不是由 Spring 管理的,因此您无法使用 @KafkaListener 注释。如果 FooUtil 是一个由 Spring 管理的 bean,它将被 Spring 拾取并且监听器注释将导致 Spring 连接监听器。我相信所有这些都是由 Spring 在 KafkaListenerAnnotationBeanPostProcessor 中完成的。

FooUtil 必须是非托管 bean 吗?我可能会遗漏一些细节,但从问题中我看不出为什么它不应该是可能的。如果您需要为使用它的每个 bean 使用不同的实例,您可以在 FooUtil 上使用 @Scope("prototype")

事实证明,您可以在不使用 @KafkaListener 注释的情况下创建一个 kafka 侦听器(感谢 Gary Russell)。只需按照此处 (douevencode.com) 的说明进行操作即可。