Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:

>> GET ACCESS NOW

NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

In this quick tutorial, we'll learn how to inject a map from a YAML file in Spring Boot.

First, we'll start with a little bit of insight on YAML files in Spring Framework. Then we'll demonstrate how to bind YAML properties to a Map with a practical example.

2. YAML Files in Spring Framework

Using YAML files to store external configuration data is a common practice among Spring developers. Basically, Spring supports YAML documents as an alternative to properties, and uses SnakeYAML under the hood to parse them.

Without further ado, let’s see what a typical YAML file looks like:

server:
  port: 8090
  application:
    name: myapplication
    url: http://myapplication.com

As we can see, the YAML file is self-explanatory and more human-readable. As a matter of fact, YAML provides a fancy and concise way to store hierarchical configuration data.

By default, Spring Boot reads configuration properties from application.properties or application.yml at application startup. However, we can use @PropertySource to load a custom YAML file.

Now that we're familiar with what a YAML file is, let's see how to inject YAML properties as a Map in Spring Boot.

3. How to Inject a Map From a YAML File

Spring Boot has taken data externalization to the next level by providing a handy annotation called @ConfigurationProperties. This annotation is introduced to easily inject external properties from configuration files directly into Java objects.

In this section, we'll focus on how to bind YAML properties into a bean class using the @ConfigurationProperties annotation.

First, we'll define some key-value properties in application.yml:

server:
  application:
    name: InjectMapFromYAML
    url: http://injectmapfromyaml.dev
    description: How To Inject a map from a YAML File in Spring Boot
  config:
    ips:
      - 10.10.10.10
      - 10.10.10.11
      - 10.10.10.12
      - 10.10.10.13
    filesystem:
      - /dev/root
      - /dev/md2
      - /dev/md4
  users: 
    root:
      username: root
      password: rootpass
    guest:
      username: guest
      password: guestpass

In this example, we'll try to map application into a simple Map<String, String>. Similarly, we'll inject config details as a Map<String, List<String>>, users as a Map with String keys, and objects belonging to a user-defined class (Credential) as values.

Then we'll create a bean class, ServerProperties, to encapsulate the logic of binding our configuration properties to Maps:

@Component
@ConfigurationProperties(prefix = "server")
public class ServerProperties {

    private Map<String, String> application;
    private Map<String, List<String>> config;
    private Map<String, Credential> users;

    // getters and setters

    public static class Credential {
    	
        private String username;
        private String password;
        
        // getters and setters
        
    }
}

As we can see, we decorated the ServerProperties class with @ConfigurationProperties. That way, we tell Spring to map all the properties with the specified prefix to an object of ServerProperties.

Recall that our app needs to be enabled for configuration properties as well, though this is done automatically in most Spring Boot applications.

Finally, we'll test if our YAML properties are properly injected as Maps:

@RunWith(SpringRunner.class)
@SpringBootTest
class MapFromYamlIntegrationTest {

    @Autowired
    private ServerProperties serverProperties;

    @Test
    public void whenYamlFileProvidedThenInjectSimpleMap() {
        assertThat(serverProperties.getApplication())
          .containsOnlyKeys("name", "url", "description");

        assertThat(serverProperties.getApplication()
          .get("name")).isEqualTo("InjectMapFromYAML");
    }

    @Test
    public void whenYamlFileProvidedThenInjectComplexMap() {
        assertThat(serverProperties.getConfig()).hasSize(2);

        assertThat(serverProperties.getConfig()
          .get("ips")
          .get(0)).isEqualTo("10.10.10.10");

        assertThat(serverProperties.getUsers()
          .get("root")
          .getUsername()).isEqualTo("root");
    }

}

4. @ConfigurationProperties vs @Value

Now let's do a quick comparison of @ConfigurationProperties and @Value.

Despite the fact that both annotations can be used to inject properties from configuration files, they are quite different. The major difference between these two annotations is that each one serves a different purpose.

In short, @Value allows us to directly inject a particular property value by its key. However, @ConfigurationProperties annotation binds multiple properties to a particular object, and provides access to the properties through the mapped object.

In general, Spring recommends using @ConfigurationProperties over @Value when it comes to injecting configuration data. @ConfigurationProperties offers a great way to centralize and group configuration properties in a structured object that we can inject later into other beans.

5. Conclusion

In this brief article, we discussed how to inject a Map from a YAML file in Spring Boot. Then we highlighted the difference between @ConfigurationProperties and @Value.

As usual, the complete source code for this article is available over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:

>> GET ACCESS NOW

Generic footer banner
8 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!