I have the following classes:
@Getter
@Setter
@Configuration
@Validated
@ConfigurationProperties(prefix = "event-processor.topic")
public class TopicProperties {
@NestedConfigurationProperty
private InputTopicProperties input;
@NestedConfigurationProperty
private OutputTopicProperties output;
}
@Getter
@Setter
@Validated
@Configuration
public class InputTopicProperties {
/**
* Input topic to read from. Must exist.
*/
@NotEmpty
private String name;
}
@Getter
@Setter
@Validated
@Configuration
public class OutputTopicProperties {
@NotEmpty
private String name;
@Min(1)
@Max(18)
private int numPartitions = 12;
// ... other fields
}
@Getter
@Setter
@Validated
@Configuration
@ConfigurationProperties(prefix = "event-processor.broker")
@EnableConfigurationProperties
public class BrokerProperties {
@NotEmpty
private String applicationId = "event-processor-streams-app";
@NotEmpty
private String bootstrapServers = "kafka:9092";
// ... other fields
}
Together with the following application config:
event-processor:
broker:
application-id: test
bootstrap-servers: localhost:29092
topic:
input:
name: mytopic
output:
name: myoutput
Using Spring Boot 2.6.9
(I know, a bit old) I was able to keep all default that I had written (e.g. brokerProperties.applicationId
, outputTopicProperties.partitions
) and selectively override.
After switching to Spring Boot 3.2.5
, I have the following behaviour:
- I cannot override the default that I have provided in the source code
- Nested configuration properties are not injected (e.g.
topicProperties.getInput() == null
)
Here is my main class:
@Log4j2
@SpringBootApplication
@RequiredArgsConstructor
//@ConfigurationPropertiesScan // tried this as well, did not help
public class ExtractorApplication {
private final BrokerProperties brokerProperties;
private final TopicProperties topicProperties;
public static void main(String[] args) {
SpringApplication.run(ExtractorApplication.class, args);
}
@PostConstruct
public void logBrokerAndTopicInfo() {
// gives only defaults
logFromClass("application Id - {}", brokerProperties.getApplicationId());
// gives only defaults
logFromClass("connected to broker {}", brokerProperties.getBootstrapServers());
// NPE
logFromClass("reading from {}", topicProperties.getInput().getName());
// NPE
logFromClass("writing to {}", topicProperties.getOutput().getName());
}
private void logFromClass(String pattern, String msg) {
log.info("{}: " + pattern, ExtractorApplication.class.getSimpleName(), msg);
}
}
What am I doing wrong?