Created
May 22, 2020 11:44
-
-
Save rlindooren/15e692516e66050056b5827746668dbe to your computer and use it in GitHub Desktop.
Spring: inject Map from additional YAML properties file with @propertysource and @ConfigurationProperties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
someMap: | |
key1: [a, b, c] | |
key2: [d, e, f] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package foo; | |
import lombok.Data; | |
import org.springframework.boot.context.properties.ConfigurationProperties; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.context.annotation.PropertySource; | |
import java.util.List; | |
import java.util.Map; | |
@Configuration | |
// E.g. as environment variable: `EXPORT ADDITIONAL_YAML_CONFIG_PATH=file:/path/to/additional.yaml` | |
@PropertySource(value = "${additional-yaml-config-path}", factory = YamlPropertySourceFactory.class) | |
@ConfigurationProperties(prefix = "additional-yaml-config") | |
@Data | |
public class SomeProperties { | |
private Map<String, List<String>> someMap; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package foo; | |
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; | |
import org.springframework.core.env.PropertiesPropertySource; | |
import org.springframework.core.env.PropertySource; | |
import org.springframework.core.io.support.EncodedResource; | |
import org.springframework.core.io.support.PropertySourceFactory; | |
import java.util.Properties; | |
/** | |
* Makes it possible to use YAML as input for @PropertySource and @ConfigurationProperties. | |
* Originally found here: https://www.baeldung.com/spring-yaml-propertysource, | |
* but adapted to be able to parse maps and keep their original structure (not as properties for each key in the map). | |
*/ | |
public class YamlPropertySourceFactory implements PropertySourceFactory { | |
public static String prefix = "additional-yaml-config"; | |
@Override | |
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) { | |
final YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean() { | |
// Overriding this method so that we can add a map, as an actual map, to the properties, | |
// without it being converted to separate properties per key | |
@Override | |
protected Properties createProperties() { | |
final Properties result = new Properties(); | |
process((properties, map) -> | |
map.keySet().forEach(key -> { | |
// Add the prefix to the key | |
// The prefix allows: @ConfigurationProperties(prefix = "additional-yaml-config") | |
final String keyInProperties = String.format("%s.%s", prefix, key); | |
result.put(keyInProperties, map.get(key)); | |
}) | |
); | |
return result; | |
} | |
}; | |
factory.setResources(encodedResource.getResource()); | |
final Properties properties = factory.getObject(); | |
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment