Daniel
Daniel

Reputation: 2500

How to autowire @ConfigurationProperties into @Configuration?

I have a properties class defined like this:

@Validated
@ConfigurationProperties(prefix = "plugin.httpclient")
public class HttpClientProperties {
   ...
}

And a configuration class like this:

@Configuration
@EnableScheduling
public class HttpClientConfiguration {

    private final HttpClientProperties httpClientProperties;

    @Autowired
    public HttpClientConfiguration(HttpClientProperties httpClientProperties) {
        this.httpClientProperties = httpClientProperties;
    }

    ...
}

When starting my spring boot application, I'm getting

Parameter 0 of constructor in x.y.z.config.HttpClientConfiguration required a bean of type 'x.y.z.config.HttpClientProperties' that could not be found.

Is this not a valid use case, or do I have to declare the dependencies some how?

Upvotes: 16

Views: 24803

Answers (2)

Unmitigated
Unmitigated

Reputation: 89517

In Spring Boot 2.2.1+, add the @ConfigurationPropertiesScan annotation to the application. (Note that this was enabled by default in version 2.2.0.) This will allow all classes annotated with @ConfigurationProperties to be picked up without using @EnableConfigurationProperties or @Component.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Also, to generate metadata for the classes annotated with @ConfigurationProperties, which is used by IDEs to provide autocompletion and documentation in application.properties, remember to add the following dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

Upvotes: 1

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44755

This is a valid use case, however, your HttpClientProperties are not picked up because they're not scanned by the component scanner. You could annotate your HttpClientProperties with @Component:

@Validated
@Component
@ConfigurationProperties(prefix = "plugin.httpclient")
public class HttpClientProperties {
    // ...
}

Another way of doing so (as mentioned by Stephane Nicoll) is by using the @EnableConfigurationProperties() annotation on a Spring configuration class, for example:

@EnableConfigurationProperties(HttpClientProperties.class) // This is the recommended way
@EnableScheduling
public class HttpClientConfiguration {
    // ...
}

This is also described in the Spring boot docs.

Upvotes: 21

Related Questions