Search code examples
javaspringspring-mvcspring-bootjavabeans

Spring Boot Convention for Variables


So I have an application.yml file for my spring boot application like so:

spring:
  url: localhost
email:
  from: [email protected]
app:
  uuid: 3848348j34jk2dne9

I want to wire these configuration properties into different components in my app like so:

@Component
public class FooA {
    private final String url;

    public FooA(@Value("${spring.url}") String url) {
        this.url = url
    }
}

@Component
public class FooB {
    private final String from;

    public FooA(@Value("${email.from}") String from) {
        this.from = from
    }
}

@Component
public class FooC {
    private final String uuid;

    public FooA(@Value("${app.uuid}") String uuid) {
        this.uuid = uuid
    }
}

The above works as intended in my application. But my question is if this is best practice in spring boot. The only other alternative to this that I know of is to use a Properties object by creating a bean inside of a configuration class, loading the properties with all the configuration variables and autowire the property bean into the components.

What is the best practice in this case?


Solution

  • As you have identified your two main choices for injecting configuration are using either @Value on individual properties or @ConfigurationProperties on a javabean configuration object.

    Which one you use comes down to preference. Personally I prefer using a configuration object.

    Using @ConfigurationProperties allows you to use JSR-303 bean validation.
    You can also write your own custom validation in the setter of your javabean if you desire.
    You can annotate config beans from non-spring projects, which allows you to write libraries that are easily configured but don’t depend on spring.
    You can generate IDE meta-data from the objects that may make your development process smoother.

    Here are some practices I recommend when using spring configuration.

    • Create individual @ConfigurationProperties objects for logical components of your application. Try to keep things modular and avoid creating a dumping ground for your entire applications config.

    • Don’t use the same @Value property in multiple locations.
      If the same configuration is needed in multiple places within your application then you should probably move the value into a config object.
      Using the same property across multiple @Value annotations makes it harder to reason around, and it can also cause unexpected behaviour if you define a default value by way of a "SpEL" expression in one place and not the other.

    • Don't define your own properties in the spring namespace.
      For example your spring.url property is not one of the properties defined in the documentation.
      By using the same name space you run the risk of that name being used for something in future spring-boot versions.