Ever wondered how defining a property in Spring applications can automatically configure functionality? We are going to create this ourselves with Spring autoconfigure.

We are going to setup a controller with endpoint with only a dependency and a property.

For a more in depth discussion of all the possibilities read the Spring documentation on this subject here.

How it works

Basically we want to tell Spring what beans we want without knowing what packages to scan. There is a special place for this. Spring looks at ~/java/resouces/META-INF/spring.factories. In here we define our bean (or mulitple beans if we want). The complete code of this library is here.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.sybrenbolandit.exclamation.config.ExclamationControllerConfig

The config we import defines the controller we want to autoconfigure:

@Configuration
public class ExclamationControllerConfig {

    @Value("${exclamation.controller.number.signs:1}")
    private int numberOfSigns;

    @Bean
    @ConditionalOnMissingBean
    public ExclamationService exclamationService() {
        return new ExclamationService(numberOfSigns);
    }

    @Bean
    @ConditionalOnMissingBean
    public ExclamationController exclamationController() {
        return new ExclamationController(exclamationService());
    }
}

Here we see the property that regulates the exclamation functionality. This can be set in the application that imports our autoconfigure. Moreover we define the bean tree up to the controller containing our endpoint.

The @ConditionalOnMissingBean annotation restricts the autoconfigure. If there is already a bean of this type this config will not instantiate a new one. There are more options for conditionally creating beans. These can react on present or missing classes, beans, properties or even resources (e.g. files with initialisation data).

The classes we configure with autoconfigure can be in another module and do not even have to be using any Spring. In this way we can decouple the business logic from the framework used for the rest interface.

Import autoconfigure

We are going to reuse an application that we made in an earlier post (found here). It’s just a basic setup with a greetings endpoint. The code that is used is found on github here.

As I stated in the introduction, the only things we need to configure our Exclamation controller is the dependency

<dependency>
    <groupId>org.sybrenbolandit</groupId>
    <artifactId>autoconfigure-exclamation-controller</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

and the property (if we don’t want the default number)

exclamation.controller.number.signs=3

When we run our application our new endpoint is automatically configured

Screenshot 2019 08 26 at 09.06.22 - SPRING AUTOCONFIGURE

Hopefully you can now create your own autoconfiguration and use its power at will. Happy autoconfiguring!