What difference does @EnableConfigurationProperties make if a bean is already annotated with @ConfigurationProperties?

JavaSpringSpring Boot

Java Problem Overview


The Spring Boot documentation says that to use the @ConfigurationProperties annotation

> You also need to list the properties classes to register in the > @EnableConfigurationProperties annotation, as shown in the following > example:

and gives this code:

@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}

But in the very next paragraph says:

> Even if the preceding configuration creates a regular bean for > AcmeProperties, we recommend that @ConfigurationProperties only deal > with the environment and, in particular, does not inject other beans > from the context. Having said that, the @EnableConfigurationProperties > annotation is also automatically applied to your project so that any > existing bean annotated with @ConfigurationProperties is configured > from the Environment.

Suggesting that listing a @ConfigurationProperties bean under an @EnableConfigurationProperties annotation is not necessary.

So which is it? Experimentally, I've seen that if I annotate a bean with @ConfigurationProperties it gets properties injected to it as expected without needing to list it in @EnableConfigurationProperties, but if this is the case then why list anything that has a @ConfigurationProperties annotation under @EnableConfigurationProperties, as is shown in the documentation? Does it make any kind of difference?

Java Solutions


Solution 1 - Java

As M. Deinum referred @EnableConfigurationProperties Is for enabling support of @ConfigurationProperties. If you take a look to the annotation Java Doc you can see:

> Enable support for ConfigurationProperties annotated beans. ConfigurationProperties beans can be registered in the standard way (for example using Bean @Bean methods) or, for convenience, can be specified directly on this annotation. [...]

For example, let's say you have a class whose responsibility is to read and store information from your application.yml / application.properties that is required to make a connection to different databases. You annotate it with @ConfigurationProperties.

Then, you typically have a @Configuration annotated class that provides a DataSource @Bean to your application. You can use the @EnableConfigurationProperties to link it to the @ConfigurationProperties class and init your data sources accordingly.

Here is a small example:

application.yml

data-sources:
  db1:
    url: "jdbc:postgresql://localhost:5432}/db1"
    username: test
    password: test
  db2:
    url: "jdbc:postgresql://localhost:5432}/db2"
    username: test
    password: test

DataSourcesConfiguration

@ConfigurationProperties
public class DataSourcesConfiguration {

    private Map<String, BasicDataSource> dataSources;

    public void setDataSources(Map<String, BasicDataSource> dataSources) {
        this.dataSources = dataSources;
    }

    Map<String, BasicDataSource > getDataSources() {
        return dataSources;
    }
}

DataSourceConnectionConfiguration

@Configuration
@EnableConfigurationProperties(DataSourcesConfiguration.class)
public class DatabaseConnectionConfiguration implements Provider<Connection> {

    private DataSourcesConfiguration dataSourcesConfiguration;

    public DatabaseConnectionConfiguration(DataSourcesConfiguration dataSourcesConfiguration) {
        this.dataSourcesConfiguration = dataSourcesConfiguration;
    }

    @Bean
    public DataSource dataSource() {
        // Use dataSourcesConfiguration to create application data source. E.g., a AbstractRoutingDataSource..
    }

}

Solution 2 - Java

It took me a while to reach to this post but would like to add here so that others may get benefited.

@ConfigurationProperties - Used to bind a class with an externalized property file. Very powerful and must be used to separate out bean classes with configuration entity class.

@Configuration - Creates a Spring bean of configuration stereotype.

@EnableConfigurationProperties - Creates a binding between a configuration entity class and Spring configuration stereotype so that after injection within a service properties can be retrieved easily.

Solution 3 - Java

If we look at the code below:

@Configuration @EnableConfigurationProperties @ConfigurationProperties(prefix="ar1") public class ar1Settings { }

  • @Configuration tells Spring to treat this as a configuration class and register it as a Bean

  • @EnableConfigurationProperties tells Spring to treat this class as a consumer of application.yml/properties values

  • @ConfigurationProperties tells Spring what section this class represents.

My understanding is that if you don't need to specify the section of the property file, then @ConfigurationProperties can be omitted.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJ PersonView Question on Stackoverflow
Solution 1 - JavaEmanuel MirandaView Answer on Stackoverflow
Solution 2 - JavaalphaView Answer on Stackoverflow
Solution 3 - JavaAR1View Answer on Stackoverflow