0

The requirement is the same as the question posted here Injecting array of values from properties file in spring boot i.e. consuming a list of related properties defined in an application.properties file.

The thing is, my code uses Core Spring. How can I achieve the same without having to bring in Spring Boot in order to use @ConfigurationProperties ? Using a comma separated list of values won't work in the long term because i wish to express a list of config objects, not just a list of strings

Thanks

Vinay B
  • 673
  • 8
  • 21

2 Answers2

0

You can look at using Apache Commons Configuration which provides rich set of methods to work with properties.

If you want to stick to property files, you can look at using this page for list and arrays:-

List<Object> colorList = config.getList("colors.pie");

Or you can use XML based hierarchical configurations and use things like:-

List<HierarchicalConfiguration<ImmutableNode>> fields = config.configurationsAt("tables.table(0).fields.field");

and

List<Object> fieldNames = config.getList("tables.table(0).fields.field.name");

Read their user-guide, you should find what you are looking for.

Kartik
  • 7,677
  • 4
  • 28
  • 50
  • Thanks, I was hoping to find a Spring way to accomplish this without having to bring in a third party library. – Vinay B Jan 10 '19 at 17:03
0

If you can add the spring-boot jar as a dependency you can use @ConfigurationProperties with core spring.

package com.stackoverflow.q54119803;

import static java.util.stream.Collectors.*;
import static org.junit.Assert.*;

import java.util.List;
import java.util.stream.Stream;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;

@SuppressWarnings("javadoc")
public class So54119803 {

    /** The Constant SPRING_CLASS_RULE. */
    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    final String anotherPropValue = "anotherPropValue";
    final List<String> expected = Stream.of("string1", this.anotherPropValue)
        .collect(toList());

    /** The spring method rule. */
    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    @Autowired
    Props props;

    @Test
    public void test() {

        System.out.println(this.props);

        assertEquals(this.anotherPropValue, this.props.getAnotherProp());
        assertEquals(String.class, this.props.getClazz());
        assertEquals(this.expected, this.props.getStrings());

    }

    @Configuration
    @EnableConfigurationProperties
    static class Config {

        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {

            final ClassPathResource location = new ClassPathResource("props.properties");
            final PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();

            propertySourcesPlaceholderConfigurer.setLocation(location);
            return propertySourcesPlaceholderConfigurer;
        }

        @Bean
        @ConfigurationProperties("test")
        Props props() {
            return new Props();
        }

    }

    static class Props {

        String anotherProp;

        List<String> strings;

        Class<?> clazz;

        public String getAnotherProp() {
            return this.anotherProp;
        }

        public void setAnotherProp(String anotherProp) {
            this.anotherProp = anotherProp;
        }

        public List<String> getStrings() {
            return this.strings;
        }

        public void setStrings(List<String> strings) {
            this.strings = strings;
        }

        public Class<?> getClazz() {
            return this.clazz;
        }

        public void setClazz(Class<?> clazz) {
            this.clazz = clazz;
        }

        @Override
        public String toString() {
            return "Props [anotherProp=" + this.anotherProp + ", strings=" + this.strings + ", clazz=" + this.clazz
                    + "]";
        }

    }
}

Sample props file: props.properties

#Conversions and references work fine
test.anotherProp=anotherPropValue
test.strings=string1,${test.anotherProp}
test.clazz=java.lang.String

Dependencies in example:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot</artifactId>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <scope>test</scope>
</dependency>
Jeff
  • 3,712
  • 2
  • 22
  • 24
  • Thanks for your comprehensive answer, but I was hoping to avoid including Spring Boot – Vinay B Jan 10 '19 at 16:09
  • I wasn't sure from you question if you didn't want to be in a spring boot context or if you didn't want to have the jar as a dependency at all. – Jeff Jan 10 '19 at 18:36
  • I will have the non-boot version up shortly. – Jeff Jan 10 '19 at 18:53