SpringBoot 2 无法绑定 ConfigurationProperties
Posted
技术标签:
【中文标题】SpringBoot 2 无法绑定 ConfigurationProperties【英文标题】:SpringBoot 2 fails to bing ConfigurationProperties 【发布时间】:2020-05-21 16:20:38 【问题描述】:我的属性如下:
@Component
@Validated
@ConfigurationProperties("kafka")
public class KafkaProperties
@NotEmpty
String broker;
@NotEmpty
String groupId;
@NotEmpty
String resetOffset = "latest";
@NotEmpty
String topic;
我的 application.properties 像:
kafka.broker=localhost:9092
kafka.groupid=pdp-group
kafka.offset-reset=latest
kafka.topic=pdp-product-fragment
测试是:
@ExtendWith(SpringExtension.class)
@Import(ReactiveKafkaConsumerTest.TestConfig.class)
@PropertySource("classpath:application.properties")
class ReactiveKafkaConsumerTest
@RegisterExtension
static final SharedKafkaTestResource sharedKafkaTestResource = new SharedKafkaTestResource();
static class TestConfig extends KafkaConfig
Consumer<ReceiverRecord<String, String>> mockConsumer = mock(Consumer.class);
@Override
List<String> topics()
String topicName = Integer.toHexString(Math.abs(new Random().nextInt()));
var kafkaTestUtils = sharedKafkaTestResource.getKafkaTestUtils();
kafkaTestUtils.createTopic(topicName, 4, (short) 1);
return asList(topicName);
@Override
public Map<String, Object> consumerProps()
Map<String, Object> props = super.consumerProps();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, sharedKafkaTestResource.getKafkaConnectString());
props.put(ConsumerConfig.GROUP_ID_CONFIG, "group");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
return props;
@Override
public Supplier<Consumer<ReceiverRecord<String, String>>> consumerSupplier()
return () -> mockConsumer;
@Autowired
List<String> topics;
@Autowired
TestConfig testConfig;
@Test
@DirtiesContext
public void testReceiveMessages()
var kafkaTestUtils = sharedKafkaTestResource.getKafkaTestUtils();
IntStream.range(0, 4)
.forEach(i -> kafkaTestUtils.produceRecords(4, topics.get(0), i));
ArgumentCaptor<ReceiverRecord<String, String>> captor = ArgumentCaptor.forClass(ReceiverRecord.class);
verify(testConfig.mockConsumer, timeout(10000).times(16))
.accept(captor.capture());
var recordsPerPartition = captor.getAllValues().stream()
.collect(Collectors.groupingBy(r -> r.partition()));
assertThat(recordsPerPartition.keySet(), containsInAnyOrder(0, 1, 2, 3));
assertEquals(16, recordsPerPartition.values().stream().mapToInt(l -> l.size()).sum());
它失败了:
Caused by: org.springframework.boot.context.properties.bind.validation.BindValidationException: Binding validation errors on kafka
- Field error in object 'kafka' on field 'broker': rejected value [null]; codes [NotEmpty.kafka.broker,NotEmpty.broker,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [kafka.broker,broker]; arguments []; default message [broker]]; default message [must not be empty]
- Field error in object 'kafka' on field 'topic': rejected value [null]; codes [NotEmpty.kafka.topic,NotEmpty.topic,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [kafka.topic,topic]; arguments []; default message [topic]]; default message [must not be empty]
- Field error in object 'kafka' on field 'groupId': rejected value [null]; codes [NotEmpty.kafka.groupId,NotEmpty.groupId,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [kafka.groupId,groupId]; arguments []; default message [groupId]]; default message [must not be empty]
我尝试了很多方法,例如:
添加 SpringBootTest 替换 PropertySource 为 TestPropertySourceSpring boot 版本为:2.2.2.RELEASE
有人有想法吗?
【问题讨论】:
【参考方案1】:将属性或 yaml 文件绑定到 POJO 是 Spring Boot 功能 Loading YAML,因此如果您想在测试期间使用它,您需要使用 @SpringBootTest 加载测试应用程序上下文。我也建议使用 @Configuration 与 @Configurationproperties。请参阅here 了解更多信息
注意:如果我们不在POJO中使用@Configuration,那么我们需要在主Spring应用类中添加@EnableConfigurationProperties(ConfigProperties.class)来将属性绑定到POJO中:
【讨论】:
以上是关于SpringBoot 2 无法绑定 ConfigurationProperties的主要内容,如果未能解决你的问题,请参考以下文章
Springboot jpa:实体无法绑定不在表列中的自定义查询中的数据
SpringBoot中@EnableAutoConfiguration注解用法收集