Using Spring-Boot configuration properties in your own classes

When writing a Spring-Boot application it is possible to use your own custom configuration classes which are injected by spring into your application and which  are configured in the application.properties file. There is even support for autocomplete support in the properties file editor in IntelliJ IDEA (I suppose there is something similar in Eclipse or NetBeans, but I haven’t tried that). This post shows how to achieve this.

Basically this is used for auto configuration of Spring-Boot components, but can be used in the Spring-Boot application as well.

The configuration class

Let’s assume we have a class named Support which represents our configuration:

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package com.sothawo.sbconfig;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Component
@ConfigurationProperties(prefix = "support")
public class Support {

    private Integer productId;

    private Contact contact;


    public Contact getContact() {
        return contact;
    }

    public void setContact(Contact contact) {
        this.contact = contact;
    }

    public Integer getProductId() {
        return productId;
    }

    public void setProductId(Integer productId) {
        this.productId = productId;
    }

    @Override
    public String toString() {
        return "Support{" +
                "productId=" + productId +
                ", contact=" + contact +
                '}';
    }

    public static class Contact {

        private String name;

        private String email;

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Contact{" +
                    "name='" + name + '\'' +
                    ", email='" + email + '\'' +
                    '}';
        }
    }
}

This is a plain POJO; it contains an inner class, but that is only for the purpose of showing how Spring Boot configures a field that is itself a class. What marks this as a configuration class is the @ConfigurationProperties annotation, which by it’s prefix argument defines the prefix string to use in the properties file.

Edit 2015-09-21: added missing @Component annotation.

Enable the Spring Boot annotation processor

To have the annotation processed it is necessary to add the following dependency to the project’s pom.xml (notice that it’s optional):

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

After compiling the project there is a new file in the target/META-INF directory named spring-configuration-metadata.json. This is needed for autocomplete support, it contains the names, types and class information of the configuration class:

{
  "groups": [
    {
      "name": "support",
      "type": "com.sothawo.sbconfig.Support",
      "sourceType": "com.sothawo.sbconfig.Support"
    },
    {
      "name": "support.contact",
      "type": "com.sothawo.sbconfig.Support$Contact",
      "sourceType": "com.sothawo.sbconfig.Support",
      "sourceMethod": "getContact()"
    }
  ],
  "properties": [
    {
      "name": "support.contact.email",
      "type": "java.lang.String",
      "sourceType": "com.sothawo.sbconfig.Support$Contact"
    },
    {
      "name": "support.contact.name",
      "type": "java.lang.String",
      "sourceType": "com.sothawo.sbconfig.Support$Contact"
    },
    {
      "name": "support.product-id",
      "type": "java.lang.Integer",
      "sourceType": "com.sothawo.sbconfig.Support"
    }
  ]
}

Using the configuration object

The configuration object is used by injecting it in a Spring bean, for example like this:

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package com.sothawo.sbconfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Component
@EnableConfigurationProperties(Support.class)
public class SupportInfo {
    @Autowired(required = false)
    private Support support;

    @PostConstruct
    public void init() {
        if (null == support) {
            System.out.println("no support");
        } else {
            System.out.println(support.toString());
        }
    }
}

Configuring the object

IntelliJ supports editing the application.properties file with code completion:

sbcfg01

This shows the available configuration properties as well as their types and default values (if the fields of the configuration class are initialized with values). The screenshot shows how field names and inner classes are mapped to the corresponding property entries.

Leave a Reply

Your email address will not be published. Required fields are marked *