我正在使用ConfigurableListableBeanFactory和registerSingleton方法动态创建bean,之后我想使用EventListener监听事件。 在示例中,Kafka侦听器正确接收到消息,但未触发EventListener,这是因为BeanFactory不支持ApplicationEvents,那么如何将EventListener添加到BeanFactory?
致谢!
@PostConstruct
public void setup() {
final ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
kafkaConfiguration.getTopics().keySet().forEach(key -> {
Topic topic = kafkaConfiguration.getTopics().get(key);
DefaultKafkaConsumerFactory<String, KafkaEntity> defaultKafkaConsumerFactory = new DefaultKafkaConsumerFactory<>(
consumerConfigs(),
new StringDeserializer(),
new JsonDeserializer<>(topic.getClazz()));
beanFactory.registerSingleton(key, defaultKafkaConsumerFactory);
ConcurrentKafkaListenerContainerFactory<String, KafkaEntity> concurrentKafkaListenerContainerFactory =
new ConcurrentKafkaListenerContainerFactory<>();
concurrentKafkaListenerContainerFactory.setConsumerFactory(defaultKafkaConsumerFactory);
concurrentKafkaListenerContainerFactory.setConcurrency(topic.getConcurrency());
concurrentKafkaListenerContainerFactory.setAutoStartup(topic.isAutoStart());
concurrentKafkaListenerContainerFactory.getContainerProperties().setPollTimeout(kafkaConfiguration.getPollTimeout());
concurrentKafkaListenerContainerFactory.getContainerProperties().setIdleEventInterval(1000L);
beanFactory.registerSingleton(CONTAINER_FACTORY_NAME + key, concurrentKafkaListenerContainerFactory);
}
@KafkaListener(id = "kfktest", topics = "data_common-apibridge-service.board", idIsGroup = false,
containerFactory = KafkaConsumerConfiguration.CONTAINER_FACTORY_NAME + "BOARD")
public void listen(@Payload(required = false) BoardMessage message,
@Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) String key) {
// TODO message handler
}
@EventListener(condition = "event.listenerId.startsWith('kfktest-')")
public void eventHandler(ListenerContainerIdleEvent event) {
log.info(event.getListenerId());
}
答案 0 :(得分:0)
经过一些阅读后,我发现了如何做到这一点,我使用了BeanFactoryPostProcessor来动态定义配置服务器中所有的bean,例如:
public static BeanFactoryPostProcessor beanFactoryPostProcessor(@Value("${kafka.topicNames}") String topicNames) {
此后,我使用@Postconstruct在另一个@Configuration中完成Bean,以便已实例化某些依赖项。
@Bean
public static BeanFactoryPostProcessor beanFactoryPostProcessor(@Value("${kafka.topicNames}") String topicNames) {
return beanFactoryPostProcessor -> {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactoryPostProcessor;
List<String> topics = Arrays.asList(topicNames.split(Pattern.quote(",")));
topics.forEach(key -> {
beanDefinitionRegistry.registerBeanDefinition(KafkaConsumerConfiguration.DEFAULT_KAFKA_CONSUMER_FACTORY_NAME + key,
BeanDefinitionBuilder.genericBeanDefinition(KafkaConsumerFactory.class)
.getBeanDefinition());
beanDefinitionRegistry.registerBeanDefinition(KafkaConsumerConfiguration.CONTAINER_FACTORY_NAME + key,
BeanDefinitionBuilder.genericBeanDefinition(ConcurrentKafkaListenerContainerFactory.class)
.getBeanDefinition());
});
log.info("Topics bean defined {}", topics.size());
};
}
致谢!