This is pretty good! I couldn't find the sample, so make a note.
--Make SpringBoot read the yaml property file with a filename other than ʻapplication.yml --At that time, load a file with a profile name attached, such as ʻapplication-test.yml
.
--Map the loaded property to the Configuration class
In a multi-project configuration, I wanted to put a property file on the project side where common parts were collected, but in application.yml, it was necessary to use another name to batting with the property file on the user side.
--Specify the property file to load using @PropertySource
in the Configuration class
--@PropertySource
does not support reading yaml files, so create a class for reading so that it can be read.
The complete source code is here [https://github.com/h-okhs/SpringPropertySourceExample)
Specify the class for reading Yaml with factory
of @PropertySource
.
FooConfig.java
@Configuration
@ConfigurationProperties(prefix = "foo")
@Component
@PropertySource(value = {"classpath:/foo-config.yml",
"classpath:/foo-config-${spring.profiles.active}.yml"},
factory = YamlPropertySourceFactory.class)
@Data
public class FooConfig {
private BarConfig bar;
private BazConfig baz;
@Data
public static class BarConfig {
private String setting1;
}
@Data
public static class BazConfig {
private String setting1;
private String setting2;
}
}
A source borrowed from somewhere.
It seems that Yaml loaded using Spring's YamlPropertiesFactoryBean
is converted to Properties
and returned as PropertySource
.
YamlPropertySourceFactory.java
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource)
throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private static Properties loadYamlIntoProperties(EncodedResource resource)
throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
} catch (IllegalStateException e) {
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException) {
throw (FileNotFoundException) e.getCause();
}
throw e;
}
}
}
SpringPropertySourceTest.java
@SpringBootTest
@ActiveProfiles("test")
public class SpringPropertySourceTest {
@Autowired
FooConfig fooConfig;
@Test
public void test() {
assertThat(fooConfig.getBar().getSetting1()).isEqualTo("barbar1");
assertThat(fooConfig.getBaz().getSetting2()).isEqualTo("bazbaz2");
}
}
In SpringBoot2.3.0 or later, @PropertySource's $ {spring.profiles.active}
cannot be resolved and an error occurs. I wrote it in another article. (I ate a lot of time because of this ...)
Failed to resolve placeholder used for value of @PropertySource in SpringBoot 2.3.0 or later
Recommended Posts