74

Spring boot comes with many cool features. My favourite one is a type-safe configuration mechanism through @ConfigurationProperties and corresponding yml/properties files. I'm writing a library that configures Cassandra connection via Datastax Java driver. I want to allow developers to configure Cluster and Session objects by simply editing yml file. This is easy in spring-boot. But I want to allow her/him configure multiple connections this way. In PHP framework - Symfony it is as easy as:

doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
      customer:
        driver:   "%database_driver2%"
        host:     "%database_host2%"
        port:     "%database_port2%"
        dbname:   "%database_name2%"
        user:     "%database_user2%"
        password: "%database_password2%"
        charset:  UTF8

(this snippet comes from Symfony documentation)

Is it possible in spring-boot using ConfigurationProperties? Should I nest them?

1
  • 2
    I'm pretty sure you can't type-safely nest arbitrary numbers of subobjects (such as your connections), although it's possible you might be able to declare a Map<String,Connection> connections. If that doesn't work, perhaps make a feature request on GitHub. Commented Apr 12, 2015 at 9:43

1 Answer 1

129

You could actually use type-safe nested ConfigurationProperties.

@ConfigurationProperties
public class DatabaseProperties {

    private Connection primaryConnection;

    private Connection backupConnection;

    // getter, setter ...

    public static class Connection {

        private String host;

        // getter, setter ...

    }

}

Now you can set the property primaryConnection.host.

If you don't want to use inner classes then you can annotate the fields with @NestedConfigurationProperty.

@ConfigurationProperties
public class DatabaseProperties {

    @NestedConfigurationProperty
    private Connection primaryConnection; // Connection is defined somewhere else

    @NestedConfigurationProperty
    private Connection backupConnection;

    // getter, setter ...

}

See also the Reference Guide and Configuration Binding Docs.

10
  • 5
    As of spring boot 1.3.0.RELEASE, the inner class needs to be public, otherwise I get java.lang.IllegalAccessException: Class org.springframework.beans.BeanUtils can not access a member of class ...DatabaseProperties$Connection with modifiers "private" Commented Jan 19, 2016 at 10:05
  • 1
    How will be the getter and setter for regular class(non-inner class)?
    – kamal
    Commented Jan 17, 2017 at 6:54
  • These are regular getter and setter, just the same like in inner-classes. If you want to set the property primaryConnection.host, Spring invokes for you getPrimaryConnection().setHost(value) (very abstract and internally maybe not correct) Commented Jan 17, 2017 at 7:23
  • Why in Documentation nested class defined in PRIVATE? docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/html/…
    – Hamedz
    Commented Feb 13, 2018 at 0:50
  • I defined my classes based on your syntax. How can these properties from other class, since they are not visible from outside Commented Mar 21, 2018 at 16:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.