本文会介绍一下@KafkaListener
的工作流程,但是不会详细深入。
@KafkaListener 如何使用
spring-kafka
使用基于@KafkaListener
注解,@KafkaListener
使用方式如下
@KafkaListener(topics = "xxx")
public void testListen(List<ConsumerRecord<xxx, xxx>> records) {
...
}
在注解内指定topic
名称,当对应的topic
内有新的消息时,testListen
方法会被调用,参数就是topic
内新的消息。这个过程是异步进行的。
工作流程
上面介绍了@KafkaListener
的使用方式,到这里应该是很好奇它到底是如何工作的。
@KafkaListener
工作流程主要有以下几步:
- 解析;解析
@KafkaListener
注解。 - 注册;解析后的数据注册到
spring-kafka
。 - 监听;开始监听
topic
变更。 - 调用;调用注解标识的方法,将监听到的数据作为参数传入。
下面我们一步一步分析
解析
@KafkaListener
注解由KafkaListenerAnnotationBeanPostProcessor
类解析,后者实现了BeanPostProcessor
接口,这个接口如下
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
接口内部有2
个方法,分别在bean
初始化前后被调用。
KafkaListenerAnnotationBeanPostProcessor
内会在postProcessAfterInitialization
方法内解析@KafkaListener
注解。
注册
解析步骤里,我们可以获取到所有含有@KafkaListener
注解的类,之后这些类的相关信息会被注册到 KafkaListenerEndpointRegistry
内,包括注解所在的方法,当前的bean
等。KafkaListenerEndpointRegistry
这个类内部会维护多个Listener Container
,每一个@KafkaListener
都会对应一个Listener Container
。并且每个Container
对应一个线程。
监听
注册完成之后,每个Listener Container
会开始工作,会新启一个新的线程,初始化KafkaConsumer
,监听topic
变更等。
调用
监听到数据之后,container
会组织消息的格式,随后调用解析得到的@KafkaListener
注解标识的方法,将组织后的消息作为参数传入方法,执行用户逻辑。
总结
上面4个步骤就是@KafkaListener
工作的核心流程。