Spring Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

In this quick tutorial, we're going to learn how to inject values into an array or List from a Spring properties file.

2. Default Behavior

We're going to start with a simple application.properties file:

arrayOfStrings=Baeldung,dot,com

Let's see how Spring behaves when we set our variable type to String[]:

@Value("${arrayOfStrings}")
private String[] arrayOfStrings;
@Test
void whenContextIsInitialized_thenInjectedArrayContainsExpectedValues() {
    assertEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
}

We can see that Spring correctly assumes our delimiter is a comma and initializes the array accordingly.

We should also note that, by default, injecting an array works correctly only when we have comma-separated values.

3. Injecting Lists

If we try to inject a List in the same way, we'll get a surprising result:

@Value("${arrayOfStrings}")
private List<String> unexpectedListOfStrings;
@Test
void whenContextIsInitialized_thenInjectedListContainsUnexpectedValues() {
    assertEquals(Collections.singletonList("Baeldung,dot,com"), unexpectedListOfStrings);
}

Our List contains a single element, which is equal to the value we set in our properties file.

In order to properly inject a List, we need to use a special syntax called Spring Expression Language (SpEL):

@Value("#{'${arrayOfStrings}'.split(',')}")
private List<String> listOfStrings;
@Test
void whenContextIsInitialized_thenInjectedListContainsExpectedValues() {
    assertEquals(Arrays.asList("Baeldung", "dot", "com"), listOfStrings);
}

We can see that our expression starts with # instead of the $ that we're used to with @Value.

We should also note that we're invoking a split method, which makes the expression a bit more complex than a usual injection.

If we'd like to keep our expression a bit simpler, we can declare our property in a special format:

listOfStrings={'Baeldung','dot','com'}

Spring will recognize this format, and we'll be able to inject our List using a somewhat simpler expression:

@Value("#{${listOfStrings}}")
private List<String> listOfStringsV2;
@Test
void whenContextIsInitialized_thenInjectedListV2ContainsExpectedValues() {
    assertEquals(Arrays.asList("Baeldung", "dot", "com"), listOfStringsV2);
}

4. Using Custom Delimiters

Let's create a similar property, but this time, we're going to use a different delimiter:

listOfStringsWithCustomDelimiter=Baeldung;dot;com

As we've seen when injecting Lists, we can use a special expression where we can specify our desired delimiter:

@Value("#{'${listOfStringsWithCustomDelimiter}'.split(';')}")
private List<String> listOfStringsWithCustomDelimiter;
@Test
void whenContextIsInitialized_thenInjectedListWithCustomDelimiterContainsExpectedValues() {
    assertEquals(Arrays.asList("Baeldung", "dot", "com"), listOfStringsWithCustomDelimiter);
}

5. Injecting Other Types

Let's take a look at the following properties:

listOfBooleans=false,false,true
listOfIntegers=1,2,3,4
listOfCharacters=a,b,c

We can see that Spring supports basic types out-of-the-box, so we don't need to do any special parsing:

@Value("#{'${listOfBooleans}'.split(',')}")
private List<Boolean> listOfBooleans;

@Value("#{'${listOfIntegers}'.split(',')}")
private List<Integer> listOfIntegers;

@Value("#{'${listOfCharacters}'.split(',')}")
private List<Character> listOfCharacters;
@Test
void whenContextIsInitialized_thenInjectedListOfBasicTypesContainsExpectedValues() {
    assertEquals(Arrays.asList(false, false, true), listOfBooleans);
    assertEquals(Arrays.asList(1, 2, 3, 4), listOfIntegers);
    assertEquals(Arrays.asList('a', 'b', 'c'), listOfCharacters);
}

This is only supported via SpEL, so we can't inject an array in the same way.

6. Reading Properties Programmatically

In order to read properties programmatically, we first need to get the instance of our Environment object:

@Autowired
private Environment environment;

Then, we can simply use the getProperty method to read any property by specifying its key and expected type:

@Test
void whenReadingFromSpringEnvironment_thenPropertiesHaveExpectedValues() {
    String[] arrayOfStrings = environment.getProperty("arrayOfStrings", String[].class);
    List<String> listOfStrings = (List<String>)environment.getProperty("arrayOfStrings", List.class);

    assertEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
    assertEquals(Arrays.asList("Baeldung", "dot", "com"), listOfStrings);
}

7. Conclusion

In this quick tutorial, we've learned how to easily inject arrays and Lists through quick and practical examples.

As always, the code is available over on GitHub.

Spring bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
guest
0 Comments
Inline Feedbacks
View all comments