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:

person:
  name: hydra
  gender: male
  age: 18

Inject Environment with @Autowired and call getProperty() to retrieve values, optionally converting types or providing default values.

@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);
    }
}

The output shows the retrieved values and demonstrates acceptsProfiles and getActiveProfiles for profile detection.

true
false
pro

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.

@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);
}

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.

@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;
    }
}

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.

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(); }
    }
}

Register the listener in the main class:

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

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.

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

For multi‑document YAML files, loadAll() returns an Iterable of objects, each representing a document.

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);
    }
}

Binding to a custom class is possible with loadAs() or by constructing a Yaml instance with a specific Constructor:

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

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.

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);
}

Writing YAML is equally straightforward using writeValue():

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);
}

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring 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

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.