Three Powerful Ways to Load Custom YAML Config in Spring Boot 3
The article explains why Spring Boot's default configuration loading falls short for complex scenarios and demonstrates three concrete techniques—an EnvironmentPostProcessor, a custom PropertySourceFactory, and an ApplicationEnvironmentPreparedEvent listener—each with full code, registration steps, and runtime output.
Environment: Spring Boot 3.5.0
1. Introduction Spring Boot automatically loads application.yml and application.properties, which works for simple cases. However, the native mechanism cannot handle multi‑environment isolation, external custom configuration, or pre‑initialization requirements. For example, the @PropertySource annotation does not support YAML parsing, and some global settings must be loaded before the container starts.
To load external YAML files flexibly, the article presents three practical solutions.
2.1 Implementation – EnvironmentPostProcessor
The processor runs before the application context refresh, allowing custom manipulation of the Environment. The implementation class must be registered in META-INF/spring.factories and can implement Ordered or be annotated with @Order to control execution order.
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ClassPathResource("custom.yml"));
Properties customProperties = factory.getObject();
environment.getPropertySources().addLast(new PropertiesPropertySource("custom", customProperties));
}
}Registration in META-INF/spring.factories:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.pack.custom.env.CustomEnvironmentPostProcessorSample custom.yml:
pack:
app:
title: xxxooo
version: 1.0.0
ttl: 60000Test component to verify loading:
@Component
public class CustomEnvRunner implements CommandLineRunner {
@Value("${pack.app.title}")
private String title;
@Value("${pack.app.version}")
private String version;
@Value("${pack.app.ttl}")
private Long ttl;
@Override
public void run(String... args) throws Exception {
System.err.println("title: %s, version: %s, ttl: %s".formatted(title, version, ttl));
}
}Running the application prints the values from custom.yml (see image below).
2.2 Implementation – PropertySourceFactory
This strategy creates a PropertySource wrapper for a given resource. The custom factory parses YAML into a Properties object.
public class CustomYamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}Usage with @PropertySource:
@Component
@PropertySource(
value = {"classpath:custom.yml"},
encoding = "UTF-8",
ignoreResourceNotFound = true,
name = "custom",
factory = CustomYamlPropertySourceFactory.class)
public class CustomYamlLoader {
}2.3 Implementation – ApplicationEnvironmentPreparedEvent Listener
The listener reacts once the environment is prepared but before the ApplicationContext is created. Because the event occurs very early, the listener must also be registered via META-INF/spring.factories.
public class EnvironmentPreparedEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ClassPathResource("custom.yml"));
Properties customProperties = factory.getObject();
event.getEnvironment().getPropertySources().addLast(new PropertiesPropertySource("custom", customProperties));
}
}Registration:
org.springframework.context.ApplicationListener=\
com.pack.custom.env.EnvironmentPreparedEventListenerThe early execution ensures the custom properties are available for any subsequent bean.
The article concludes that these three approaches enable flexible, pre‑initialization loading of external YAML configuration files in Spring Boot 3, each suited to different integration points.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
