Reading a List from properties file and load with

2019-01-01 08:09发布

Similar to this question: http://forum.springsource.org/showthread.php?111992-Loading-a-list-from-properties-file-using-Value-annotation (for which there's no reply on)

I want to have a list of values in a .properties file, ie:

my.list.of.strings=ABC,CDE,EFG

And to load it in my class directly, ie:

@Value("${my.list.of.strings}")
private List<String> myList;

As I understand, an alternative of doing this is to have it in the spring config file, and load it as a bean reference (correct me if I'm wrong), ie

<bean name="list">
 <list>
  <value>ABC</value>
  <value>CDE</value>
  <value>EFG</value>
 </list>
</bean>

But is there any way of doing this? using a .properties file? ps: I would like to do this with out any custom code if possible.

13条回答
十年一品温如言
2楼-- · 2019-01-01 08:50

Consider using Commons Configuration. It have built in feature to break an entry in properties file to array/list. Combing with SpEL and @Value should give what you want


As requested, here is what you need (Haven't really tried the code, may got some typoes, please bear with me):

In Apache Commons Configuration, there is PropertiesConfiguration. It supports the feature of converting delimited string to array/list.

For example, if you have a properties file

#Foo.properties
foo=bar1, bar2, bar3

With the below code:

PropertiesConfiguration config = new PropertiesConfiguration("Foo.properties");
String[] values = config.getStringArray("foo");

will give you a string array of ["bar1", "bar2", "bar3"]

To use with Spring, have this in your app context xml:

<bean id="fooConfig" class="org.apache.commons.configuration.PropertiesConfiguration">
    <constructor-arg type="java.lang.String" value="classpath:/Foo.properties"/>
</bean>

and have this in your spring bean:

public class SomeBean {

    @Value("fooConfig.getStringArray('foo')")
    private String[] fooArray;
}

I believe this should work :P

查看更多
流年柔荑漫光年
3楼-- · 2019-01-01 08:51

If you are using latest Spring framework version(Spring 3.1+ I believe), you don't need to those string split stuff in SpringEL,

Simply add PropertySourcesPlaceholderConfigurer and DefaultConversionService in your Spring's Configuration class ( the one with annotated with Configuration ) e.g,

@Configuration
public class AppConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean public ConversionService conversionService() {
        return new DefaultConversionService();
    }
}

and in your class

@Value("${list}")
private List<String> list;

and in the properties file

list=A,B,C,D,E

Without DefaultConversionService, you can only take comma separated String into String array when you inject the value into your field, but DefaultConversionService does a few convenient magic for you and will add those into Collection, Array, etc. ( check the implementation if you'd like to know more about it )

With these two, it even handles all the redundant whitespaces including newline, so you don't need to add additional logics to trim them.

查看更多
旧人旧事旧时光
4楼-- · 2019-01-01 08:55

If you are reading this and you are using Spring Boot, you have 1 more option for this feature

Usually comma separated list are very clumsy for real world use case (And sometime not even feasible, if you want to use commas in your config):

email.sendTo=somebody@example.com,somebody2@example.com,somebody3@example.com,.....

With Spring Boot, you can write it like these (Index start at 0):

email.sendTo[0]=somebody@example.com
email.sendTo[1]=somebody2@example.com
email.sendTo[2]=somebody3@example.com

And use it like these:

@Component
@ConfigurationProperties("email")
public class EmailProperties {

    private List<String> sendTo;

    public List<String> getSendTo() {
        return sendTo;
    }

    public void setSendTo(List<String> sendTo) {
        this.sendTo = sendTo;
    }

}


@Component
public class EmailModel {

  @Autowired
  private EmailProperties emailProperties;

  //Use the sendTo List by 
  //emailProperties.getSendTo()

}



@Configuration
public class YourConfiguration {
    @Bean
  public EmailProperties emailProperties(){
        return new EmailProperties();
  }

}


#Put this in src/main/resource/META-INF/spring.factories
  org.springframework.boot.autoconfigure.EnableAutoConfiguration=example.compackage.YourConfiguration
查看更多
唯独是你
5楼-- · 2019-01-01 08:57

If you are using Spring Boot 2, it works as is, without any additional configuration.

my.list.of.strings=ABC,CDE,EFG

@Value("${my.list.of.strings}")
private List<String> myList;
查看更多
长期被迫恋爱
6楼-- · 2019-01-01 09:00

if using property placeholders then ser1702544 example would become

@Value("#{myConfigProperties['myproperty'].trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}") 

With placeholder xml:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
    <property name="properties" ref="myConfigProperties" />
    <property name="placeholderPrefix"><value>$myConfigProperties{</value></property>
</bean>    

<bean id="myConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
     <property name="locations">
         <list>
                <value>classpath:myprops.properties</value>
         </list>
     </property>
</bean> 
查看更多
旧人旧事旧时光
7楼-- · 2019-01-01 09:03

By specifying the the my.list.of.strings=ABC,CDE,EFG in .properties file and using

@Value("${my.list.of.strings}") private String[] myString;

You can get the arrays of strings. And using CollectionUtils.addAll(myList, myString), you can get the list of strings.

查看更多
登录 后发表回答