PTueller
PTueller

Reputation: 41

Spring Boot - Nested Configuration Properties are not recognized

As the title says, my custom properties are not registered when Application is starting. Would you mind taking a look?

My custom.yml:

bridge:
  url: xxx
  authentication:
    auth-url: xxx
    user: xxx

My BridgeProperties.java:

@Component
@PropertySource("classpath:custom.yml")
@ConfigurationProperties(
        prefix = "bridge"
)

public class BridgeProperties {
    @NestedConfigurationProperty
    protected ApiProperties apiProperties = new ApiProperties();
}

My ApiProperties.java:

  public class ApiProperties {
    protected String url;
    protected ApiProperties.Authentication authentication;
    // getter and setter

    public ApiProperties() {
    }

    public static class Authentication {
      protected String authUrl;
      protected String user;
      public Authentication() {}
      // getter and setter
    }

My Application's entry point:

@SpringBootApplication
@PropertySources(value = {
        @PropertySource("classpath:application.yml"),
        @PropertySource("classpath:custom.yml")
})

public class IntegrationService {
    public static void main(String... args) {
        SpringApplication.run(IntegrationService.class, args);
    }
}

When printing to the command line, I get null instead of the values I assigned to url, auth-url, and user in the custom.yml.

Upvotes: 3

Views: 5422

Answers (1)

рüффп
рüффп

Reputation: 5438

As mentioned in the Baeldung Site:

It's also worth mentioning that YAML files do not support the @PropertySource annotation, so if we need to use this annotation, it would constrain us to using a properties file.

If you really need to import additional external file in yaml format, you have to implement your own PropertySourceFactory like in this article.

For me I do not see the advantage not using the default application.yml as you can define multiple sections managed by different Properties classes.

For example, if you just put your properties in the application.yml and if you compile with a recent JDK (>=jdk 14) you can even use the record for managing your properties in a very compact manner:

What you have to do is just to add the EnableConfigurationProperties annotation:

@SpringBootApplication
@EnableConfigurationProperties(BridgeProperties.class)
public class IntegrationService {
    public static void main(String... args) {
        SpringApplication.run(IntegrationService.class, args);
    }
}

and define a record for mapping your yaml properties:

@ConfigurationProperties(prefix = "bridge")
public final record BridgeProperties(String url, Authentication authentication) {
    public record Authentication(String authUrl, String user){
    }
}

Remember you can also define environment variable in profiles like application-dev.yml if you start your app with profile dev and another one e.g. for production application-prd.yml if your profile for production is named prd. You can still keep the common properties in the application.yml.

If you really want to go in the external file path, I suggest to switch to .properties as the @PropertySource supports it natively.

Upvotes: 1

Related Questions