Changing delimiter in @ConfigurationProperties for reading a List property
Asked Answered
O

2

5

I have a list of values in one property in application.properties file:

my-property=abc,def,ghi

And I load it in my @ConfigurationProperties class:

@Configuration
@ConfigurationProperties
public class MyProperties {

    private List<String> myProperty;
}

But I don't know how to change delimiter (from comma to semicolon or other separator):

my-property=abc;def;ghi

I know I can write workaround, but I don't want to use them because:

  • @Value for property, but it requires manually writing property name for each fields (loss of @ConfigurationProperties advantages).
@Value("#{'${my-property}'.split(';')}")
private List<String> myProperty;
  • Many properties with index, but it requires manually indexing and it's arduous when there are a lot of them and you have to change the order:
my-property[0]=abc
my-property[1]=def
my-property[2]=ghi
  • Writing getter with split, but I have to write getter for all properties manually:
private String myProperties;

public List<String> getMyProperty() {
    return Arrays.asList(myProperties.split(";"));
}
Orthopedist answered 15/6, 2020 at 17:25 Comment(0)
O
5

Basic usage

The answer is annotation @Delimiter.

You can set any string as delimiter (default value is ,). For example:

@Configuration
@ConfigurationProperties
public class MyProperties {

    @Delimiter(";")
    private List<String> myProperty;
}

and application.properties file:

my-property=abc;def;ghi

Longer strings

Longer string as delimiters also works. For example annotation @Delimiter("---") with property:

my-property=abc---def---ghi

How it works under the hood

If you interested, I found this annotation by debugging Spring source code. The key is class DelimitedStringToArrayConverter (check source code to find the annotation). You can see default value , when delimiter is null.

How it works:

  • invoking setter of your property (you have to write it to set breakpoint for debugger):
    public void setMyProperty(List<String> myProperty) {
        this.myProperty = myProperty;
    }
  • CollectionBinder
  • IndexedElementsBinder
  • BindConverter
  • ApplicationConversionService
  • DelimitedStringToArrayConverter
Orthopedist answered 24/12, 2022 at 19:1 Comment(0)
E
1

I'd suggest you to switch from the properties format to the YAML format. Then your list would be easy to represent in the config:

my-app:
  my-property:
    - abc
    - def
    - ghi

The configuration bean would look as follows:

@Configuraton
@ConfigurationProperties(prefix = "my-app.my-property")
public class MyProperties {
    private List<String> myProperty;
}

Advantages: You don't need to care about indices. You can change order at any time easily. You can insert new elements or delete some elements easily. You don't need to care about parsing, separators, etc. The representations is easier to read, especially when you have many elements or if they are long: if you have 10 elements of 30 symbols each, with single line approach you will get a string of about 300 symbols, hard to read.

Enucleate answered 15/6, 2020 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.