SpringBoot Kafka生产者value.serializer被设为StringSerializer问题求助
我在SpringBoot中配置Kafka生产者时,已在自定义配置类和application.yml中明确指定value.serializer为JsonSerializer,但实际生效的却是StringSerializer,导致序列化异常:
org.apache.kafka.common.errors.SerializationException: Can't convert value of class CustomType to class org.apache.kafka.common.serialization.StringSerializer specified in value.serializer
配置详情
自定义KafkaProducerConfig类:
public class KafkaProducerConfig { @Value("${spring.kafka.bootstrap-servers}") private String bootstrapServers; public Map<String, Object> producerConfig(){ Map<String, Object> props = new HashMap<>(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); return props; } public ProducerFactory<String, CustomType> producerFactory(){ return new DefaultKafkaProducerFactory<>(producerConfig()); } @Bean public KafkaTemplate<String, CustomType> kafkaTemplate(ProducerFactory<String, CustomType> producerFactory){ return new KafkaTemplate<>(producerFactory); } }
application.yml配置:
spring: kafka: producer: value.serializer: org.springframework.kafka.support.serializer.JsonSerializer
ProducerConfig输出验证:
ProducerConfig values: ... key.serializer = class org.apache.kafka.common.serialization.StringSerializer ... value.serializer = class org.apache.kafka.common.serialization.StringSerializer
消息发送代码:
@Slf4j @Service @RequiredArgsConstructor public class KafkaTelemetryRawSend { @Autowired private KafkaTemplate<String, CustomType> kafkaTemplate; public void send(CustomType customType){ System.out.println("kafka sending"); kafkaTemplate.send("topic", customType); } }
已确认激活正确的test环境配置,Kafka集群正常,项目中仅key.serializer使用过StringSerializer。
排查方向与解决建议
检查自定义配置类是否被Spring扫描
确认KafkaProducerConfig类上添加了@Configuration注解,否则Spring不会加载该配置类,会自动创建默认的ProducerFactory(默认value.serializer为StringSerializer)。排查Bean冲突
如果项目中存在多个ProducerFactory或KafkaTemplate的Bean定义,可能导致注入的不是自定义实例。可以给自定义的KafkaTemplate添加@Qualifier("customKafkaTemplate"),注入时指定对应的Bean名称:@Bean("customKafkaTemplate") public KafkaTemplate<String, CustomType> kafkaTemplate(ProducerFactory<String, CustomType> producerFactory){ return new KafkaTemplate<>(producerFactory); } // 注入时 @Autowired @Qualifier("customKafkaTemplate") private KafkaTemplate<String, CustomType> kafkaTemplate;验证配置Map的实际内容
在producerFactory()方法中打印producerConfig()返回的props,确认JsonSerializer.class是否被正确放入配置项:public ProducerFactory<String, CustomType> producerFactory(){ Map<String, Object> props = producerConfig(); System.out.println("Producer config value.serializer: " + props.get(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG)); return new DefaultKafkaProducerFactory<>(props); }检查是否存在配置后置处理器
若项目中存在实现ProducerConfigPostProcessor的Bean,可能会修改最终配置参数,导致value.serializer被替换。排查此类Bean的逻辑。改用Spring Boot自动配置简化实现
移除自定义的KafkaProducerConfig,完全通过application.yml配置,Spring Boot会自动创建对应类型的ProducerFactory和KafkaTemplate:spring: kafka: bootstrap-servers: your-bootstrap-servers producer: key-serializer: org.apache.kafka.common.serialization.StringSerializer value-serializer: org.springframework.kafka.support.serializer.JsonSerializer确保
CustomType满足Jackson序列化要求(如提供无参构造器,或添加@JsonCreator注解处理带参构造)。确认依赖兼容性
检查spring-kafka依赖版本与Spring Boot版本兼容,JsonSerializer属于spring-kafka包,确保依赖正确引入:<dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency>
内容的提问来源于stack exchange,提问作者Icarus

