Master Spring Boot Configuration: From Environment to @Value and Beyond
This article explains multiple ways to read configuration properties in Spring Boot—including Environment, @Value, @ConfigurationProperties, @PropertySources, and custom YAML loading—detailing their underlying mechanisms, common pitfalls, and code examples so developers can choose the most suitable approach for their projects.
Reading configuration properties is one of the most common tasks in Spring Boot development, yet many developers still encounter pitfalls. This guide reviews several methods, explains their underlying principles, and provides practical code examples.
1. Environment
The Environment interface offers a simple way to obtain property values via getProperty(key). It is the core of Spring Boot's configuration system, and understanding its loading process helps diagnose issues.
@Slf4j
@SpringBootTest
public class EnvironmentTest {
@Resource
private Environment env;
@Test
public void var1Test() {
String var1 = env.getProperty("env101.var1");
log.info("Environment config value: {}", var1);
}
}What is Environment?
Environmentis Spring Boot's central interface for accessing application properties, including system properties, environment variables, command‑line arguments, and values defined in application.yml or application.properties.
Configuration Initialization
During SpringApplication.run, the method prepareEnvironment() creates a ConfigurableEnvironment, loads default and user‑defined property sources, attaches system properties, and binds them to the application context.
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments args) {
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, args.getSourceArgs());
ConfigurationPropertySources.attach(environment);
listeners.environmentPrepared(bootstrapContext, environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
bindToSpringApplication(environment);
return environment;
}The loaded properties are wrapped in PropertySource objects (e.g., MapPropertySource, PropertiesPropertySource, ResourcePropertySource, etc.) and stored in a list that the application context later uses.
2. @Value Annotation
The @Value annotation injects a single property value into a bean field, method parameter, or constructor argument. Beans must be managed by Spring (e.g., annotated with @Component, @Service, @Configuration, etc.) for the injection to work.
@Slf4j
@SpringBootTest
public class EnvVariablesTest {
@Value("${env101.var1}")
private String var1;
@Test
public void var1Test() {
log.info("Config property: {}", var1);
}
}Common pitfalls include missing properties, injecting into static or final fields, and using the annotation in non‑managed POJOs. Providing a default value (e.g., @Value("${env101.var1:default}")) avoids startup failures.
3. @ConfigurationProperties
The @ConfigurationProperties annotation binds a group of properties with a common prefix to a POJO, enabling type‑safe configuration.
@Data
@Configuration
@ConfigurationProperties(prefix = "env101")
public class MyConf {
private String var1;
private String var2;
}During the prepareEnvironment() phase, bindToSpringApplication(environment) prepares the binding, and ConfigurationPropertiesBindingPostProcessor later registers the bean and performs the actual property injection.
4. @PropertySources
When custom property files (outside application.yml) are needed, @PropertySources can load them and make the values available via @Value or Environment.getProperty(). It only supports .properties files by default; loading YAML requires a custom YamlPropertySourceFactory.
@Data
@Configuration
@PropertySources({
@PropertySource(value = "classpath:xiaofu.properties", encoding = "utf-8"),
@PropertySource(value = "classpath:xiaofu.properties", encoding = "utf-8")
})
public class PropertySourcesConf {
@Value("${env101.var10}")
private String var10;
@Value("${env101.var9}")
private String var9;
}5. Loading YAML with YamlPropertiesFactoryBean
To load YAML files directly, use YamlPropertiesFactoryBean to create a PropertySourcesPlaceholderConfigurer bean.
@Configuration
public class MyYamlConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer yamlConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("xiaofu.yml"));
configurer.setProperties(Objects.requireNonNull(yaml.getObject()));
return configurer;
}
}6. Custom Property Retrieval
If none of the built‑in methods suit your needs, you can inject PropertySources and iterate over the PropertySource list yourself.
@Slf4j
@SpringBootTest
public class CustomTest {
@Autowired
private PropertySources propertySources;
@Test
public void customTest() {
for (PropertySource<?> ps : propertySources) {
log.info("Custom config source: {} -> {}", ps.getName(), ps.getSource());
}
}
}Conclusion
Spring Boot offers several ways to access configuration: @Value for single values, Environment for direct look‑ups, @ConfigurationProperties for batch binding, and @PropertySource(s) for custom files. Choose the method that best fits your readability, maintainability, and performance requirements.
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.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
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.
