有一个Spring-boot程序正在使用kafka中的JSON数据。 Afaik设置JsonDeserializer的唯一方法是使用java配置,即它不能在.yaml(或.properties)文件中设置,例如
@Configuration
public class KafkaConfig {
@Bean
public ConsumerFactory<String, DeserObject> consumerFactory( final KafkaProperties properties ) {
JsonDeserializer<DeserObject> jsonDeserializer = new JsonDeserializer<>( DeserObject.class );
return new DefaultKafkaConsumerFactory<>(
properties.buildConsumerProperties(), // so consumer could still be configured in .yaml
new StringDeserializer(), // key deserializer
jsonDeserializer // value deserializer
);
}
@Bean
public KafkaListenerContainerFactory kafkaListenerContainerFactory( final ConsumerFactory<String, DeserObject> consumerFactory ) {
ConcurrentKafkaListenerContainerFactory<String, DeserObject> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory( consumerFactory );
return factory;
}
}
既然我们自己正在创建ListenerContainerFactory
,则无法通过.yaml设置AckMode
:
spring:
kafka:
listener:
ack-mode: manual
因为它不会被拾取(因为ListernerContainerFactory不是由boot自动配置的,因为我们正在创建它。)
所以问题是:是否有任何方式从yaml配置ackMode,或者我们必须从java中做到这一点?:
@Bean
public KafkaListenerContainerFactory kafkaListenerContainerFactory( final ConsumerFactory<String, DeserObject> consumerFactory ) {
ConcurrentKafkaListenerContainerFactory<String, DeserObject> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory( consumerFactory );
factory.getContainerProperties().setAckMode( MANUAL ); // !! AckMode needs to be set in Java
return factory;
}
我猜或者这也可以通过KafkaProperties
注入,但这感觉很糟糕:
@Bean
public KafkaListenerContainerFactory kafkaListenerContainerFactory( final KafkaProperties properties, final ConsumerFactory<String, DeserObject> consumerFactory ) {
ConcurrentKafkaListenerContainerFactory<String, DeserObject> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory( consumerFactory );
factory.getContainerProperties().setAckMode( properties.getListener().getAckMode() );
return factory;
}
答案 0 :(得分:1)
您需要使用Boot的ConcurrentKafkaListenerContainerFactoryConfigurer
来填充引导属性。这是您未提供的标准bean定义...
@Bean
@ConditionalOnMissingBean(name = "kafkaListenerContainerFactory")
public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
ConsumerFactory<Object, Object> kafkaConsumerFactory) {
ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<Object, Object>();
configurer.configure(factory, kafkaConsumerFactory);
return factory;
}