Issue
Spring boot provides an elegant way to inject the properties prefixed with a particular key into Configuration class using @ConfigurationProperties(prefix = "foo")
. That is shown href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties" rel="nofollow noreferrer">here and here. Question is, how to inject prefixed properties into java.util.Properties
instance as shown below?
@Configuration
@EnableConfigurationProperties
public class FactoryBeanAppConfig {
@Bean
@ConfigurationProperties(prefix = "kafka")
public Producer<String, String> producer(Properties properties) throws Exception {
Producer<String, String> producer = new KafkaProducer<String, String>(properties);
return producer;
}
}
Solution
That does not work, since this property injection is based on getters and setters on the object that should hold the @ConfigurationProperties
Define a class holding the properties you want like this:
@ConfigurationProperties(prefix = "kafka.producer")
public class MyKafkaProducerProperties {
private int foo;
private string bar;
// Getters and Setter for foo and bar
}
Then use it in your configuration like this
@Configuration
@EnableConfigurationProperties(MyKafkaProducerProperties.class)
public class FactoryBeanAppConfig {
@Bean
public Producer<String, String> producer(MyKafkaProducerProperties kafkaProperties) throws Exception {
Properties properties = new Properties();
properties.setProperty("Foo", kafkaProperties.getFoo());
properties.setProperty("Bar", kafkaProperties.getBar());
Producer<String, String> producer = new KafkaProducer<String, String>(properties);
return producer;
}
}
UPDATE
Since you commented that you don't want to have each property represented as java code you could use a HashMap
as the one and only property in your @ConfigurationProperties
@ConfigurationProperties(prefix = "kafka")
public class MyKafkaProducerProperties {
private Map<String, String> producer= new HashMap<String, String>();
public Map<String, String> getProducer() {
return this.producer;
}
}
In your application.properties
you can specify the properties like this:
kafka.producer.foo=hello
kafka.producer.bar=world
And in your configuration you can use it like this:
@Configuration
@EnableConfigurationProperties(MyKafkaProducerProperties.class)
public class FactoryBeanAppConfig {
@Bean
public Producer<String, String> producer(MyKafkaProducerProperties kafkaProperties) throws Exception {
Properties properties = new Properties();
for ( String key : kafkaProperties.getProducer().keySet() ) {
properties.setProperty(key, kafkaProperties.getProducer().get(key));
}
Producer<String, String> producer = new KafkaProducer<String, String>(properties);
return producer;
}
}
Answered By - Yannic Bürgmann
Answer Checked By - Willingham (JavaFixing Volunteer)