Backend Development 14 min read

Beyond @Value: 5 Powerful Ways to Read YAML in Spring Boot

This article demonstrates five practical techniques for reading YAML configuration files in Spring Boot—including Environment, YamlPropertiesFactoryBean, custom listeners, SnakeYml, and Jackson—providing code examples, usage details, and tips for handling defaults and profile activation.

macrozheng
macrozheng
macrozheng
Beyond @Value: 5 Powerful Ways to Read YAML in Spring Boot

In the previous article we examined the Spring Boot source code that parses

yml

files. This follow‑up focuses on five practical ways to read YAML configuration values beyond the common

@Value

and

@ConfigurationProperties

annotations.

1. Environment

Spring provides the

Environment

interface (which extends

PropertyResolver

) to access properties. After defining a simple

application.yml

:

<code>person:
  name: hydra
  gender: male
  age: 18
</code>

Inject

Environment

with

@Autowired

and call

getProperty()

to retrieve values, optionally converting types or providing default values.

<code>@RestController
public class EnvironmentController {
    @Autowired
    private Environment environment;

    @GetMapping("envTest")
    private void getEnv() {
        System.out.println(environment.getProperty("person.name"));
        System.out.println(environment.getProperty("person.gender"));
        Integer age = environment.getProperty("person.age", Integer.class);
        System.out.println(age);
        String defaultValue = environment.getProperty("person.other", String.class, "defaultValue");
        System.out.println(defaultValue);
    }
}
</code>

The output shows the retrieved values and demonstrates

acceptsProfiles

and

getActiveProfiles

for profile detection.

<code>true
false
pro
</code>

2. YamlPropertiesFactoryBean

Spring’s

YamlPropertiesFactoryBean

can load a custom YAML file into a

Properties

object without being limited to

application.yml

. After setting the resource path with

setResources()

, call

getObject()

to obtain the properties.

<code>@GetMapping("fcTest")
public void ymlProFctest() {
    YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
    yamlProFb.setResources(new ClassPathResource("application2.yml"));
    Properties properties = yamlProFb.getObject();
    System.out.println(properties.get("person2.name"));
    System.out.println(properties.get("person2.gender"));
    System.out.println(properties);
}
</code>

When the same bean is used in another request, the values appear as

null

. Adding a

PropertySourcesPlaceholderConfigurer

bean resolves this by loading the properties into the Spring context.

<code>@Configuration
public class PropertyConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
        yamlProFb.setResources(new ClassPathResource("application2.yml"));
        configurer.setProperties(yamlProFb.getObject());
        return configurer;
    }
}
</code>

3. Listening to Application Events

Spring Boot loads YAML files by listening to

ApplicationEnvironmentPreparedEvent

. You can create a custom listener that loads any YAML file and adds its

OriginTrackedMapPropertySource

to the environment.

<code>public class YmlListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
    private String ymlFilePath;
    public YmlListener(String ymlFilePath) { this.ymlFilePath = ymlFilePath; }
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment environment = event.getEnvironment();
        ResourceLoader loader = new DefaultResourceLoader();
        YamlPropertySourceLoader ymlLoader = new YamlPropertySourceLoader();
        try {
            List<PropertySource<?>> sourceList = ymlLoader.load(ymlFilePath, loader.getResource(ymlFilePath));
            for (PropertySource<?> propertySource : sourceList) {
                environment.getPropertySources().addLast(propertySource);
            }
        } catch (IOException e) { e.printStackTrace(); }
    }
}
</code>

Register the listener in the main class:

<code>public static void main(String[] args) {
    SpringApplication application = new SpringApplication(MyApplication.class);
    application.addListeners(new YmlListener("classpath:/application2.yml"));
    application.run(args);
}
</code>

After startup, the custom YAML source is visible in the environment (screenshots omitted for brevity).

4. SnakeYml

SnakeYml is a standalone library for parsing YAML. After adding the Maven dependency, you can use

Yaml.load()

,

Yaml.loadAll()

, or

Yaml.loadAs()

to obtain a

Map

or bind directly to POJOs.

<code>public void test1() {
    Yaml yaml = new Yaml();
    Map<String, Object> map = yaml.load(getClass().getClassLoader().getResourceAsStream("snake1.yml"));
    System.out.println(map);
}
</code>

For multi‑document YAML files,

loadAll()

returns an

Iterable

of objects, each representing a document.

<code>public void test2() {
    Yaml yaml = new Yaml();
    Iterable<Object> objects = yaml.loadAll(getClass().getClassLoader().getResourceAsStream("snake2.yml"));
    for (Object obj : objects) {
        System.out.println(obj);
    }
}
</code>

Binding to a custom class is possible with

loadAs()

or by constructing a

Yaml

instance with a specific

Constructor

:

<code>public void test3() {
    Yaml yaml = new Yaml();
    Person person = yaml.loadAs(getClass().getClassLoader().getResourceAsStream("snake1.yml"), Person.class);
    System.out.println(person);
}
</code>

5. jackson-dataformat-yaml

Jackson can also handle YAML via the

jackson-dataformat-yaml

module. Create an

ObjectMapper

with a

YAMLFactory

and read or write YAML directly.

<code>public void read() throws IOException {
    ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
    InputStream input = new FileInputStream("snake1.yml");
    Person person = objectMapper.readValue(input, Person.class);
    System.out.println(person);
}
</code>

Writing YAML is equally straightforward using

writeValue()

:

<code>public void write() throws IOException {
    Map<String, Object> map = new HashMap<>();
    SinglePerson p1 = new SinglePerson("Trunks", "male");
    SinglePerson p2 = new SinglePerson("Goten", "male");
    Person person = new Person(p1, p2);
    map.put("person", person);
    ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
    mapper.writeValue(new File("jackson-gen.yml"), map);
}
</code>

Jackson adds quotes around string values and includes a document start marker.

Conclusion

The article presented five methods for reading YAML configuration files. The first three rely on Spring’s environment, while SnakeYml and Jackson work independently of Spring. Each approach has its own strengths and suitable scenarios, so developers should choose the method that best fits their project requirements.

configurationSpring BootJacksonYAMLenvironmentSnakeYmlYamlPropertiesFactoryBean
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.