February 07, 2020

How to use YAML with Spring Boot?

What is YAML?
YAML stands for 'YAML Ain’t Markup Language'.

It is a human friendly data serialization standard for all programming languages. It is a superset of JSON, and as such is a very convenient format for specifying hierarchical configuration data.

YAML is more readable and it is good for the developers for read/write configuration files.

What is the difference between YAML(.yml) and .properties file?
  • properties file store data in sequential format, where as yml file store data in hierarchical format.
  • properties file supports only key-value pair basically string values. yml file supports key-value pair as well as map, list and scalar type values.
  • properties file is specifically used for Java. yml files are used by many of the languages like Java, Python, ROR, etc.  Elastic Search instance and MongoDB database, both of these applications use YAML(.yml) as their default configuration format.
  • For handling multiple profiles via properties files, we need to manage individual file for each profile. In case of yml file we just need to manage single file and place configuration data of specific profile inside it.
  • For Spring project, @PropertySource annotation support properties file, where as YAML files can’t be loaded via the @PropertySource annotation.
  • While retrieving the values from .yml file we get the value as whatever the respective type (int, string etc.) is in the configuration. In case of the .properties files we get strings regardless of what the actual value type is in the configuration.
NOTE: Spring Boot has great support for externalized configuration. By default, @PropertySource doesn't load YAML files. That means if we want to use the @PropertySource annotation in our application, we need to stick with the standard properties files.

As of Spring 4.3, @PropertySource comes with the factory attribute. We can make use of it to provide our custom implementation of the PropertySourceFactory, which will handle the YAML file processing.

ALSO READ: Configuring Spring Boot Application: @Value, @ConfigurationProperties

How can we use Yaml instead of properties file?
This was asked when I went to give interview for the Senior Java Developer position in Morgan Stanley.

Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean loads YAML as Properties and the YamlMapFactoryBean loads YAML as a Map.

Creating YAML
Let's create a yml file in /myproject/src/main/resources/application.yml.

In the below YAML file, we have set up properties for 2 different environments (two profiles). The properties for both the environments are seprated by dashes, which indicate the start of a new document.

The Spring application takes the first profile as the default profile, unless declared otherwise in the Spring application.



Binding YAML
Let's create a config file MyYAMLConfig and add below annotations:
  • @Configuration to mark the class as a source of bean definitions
  • @ConfigurationProperties binds and validates the external configurations to a configuration class
  • @EnableConfigurationProperties is used to enable @ConfigurationProperties annotated beans in the Spring application



Accessing YAML Properties
Its pretty simple, we just need to create an object of the YAMLConfig class and access the properties using that object. e.g:

@Autowired
private MyYAMLConfig config;

We need to set spring.active.profiles environment variable in properties file. If we don't define spring.profiles.active, it will default to the first profiles property defined in the YAML file. e.g: add the below line in application.properties to enable reading production properties,

spring.profiles.active=prod

Overriding YAML
YAML files can be overridden by other YAML properties files depending on their location.Here is the order of highest precedence first:
  • Profiles' properties placed outside the packaged jar
  • Profiles' properties packaged inside the packaged jar
  • Application properties placed outside the packaged jar
  • Application properties packaged inside the packaged jar
How can configure lists and maps using YAML and properties file?
There are two ways to assign values and store them in a list:
servers:
  - 111.11.11.11
  - 222.22.22.22
external: [111.11.11.11, 222.22.22.22]

The equivalent configuration using properties file would be more difficult to read:
servers[0]=111.11.11.11
servers[1]=222.22.22.22
external=111.11.11.11, 222.22.22.22

-K Himaanshu Shuklaa..

No comments:

Post a Comment