从属性文件中读取List并使用spring注释加载@Value

问题描述 投票:181回答:13

我想在.properties文件中有一个值列表,即:

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

并直接加载到我的班级,即:

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

据我所知,这样做的另一种方法是将它放在spring配置文件中,并将其作为bean引用加载(如果我错了,请纠正我),即

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

但有没有办法做到这一点?使用.properties文件? ps:如果可能的话,我想用任何自定义代码执行此操作。

java spring spring-properties
13个回答
379
投票

使用Spring EL:

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

假设您的属性文件已正确加载以下内容:

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

1
投票

注意值中的空格。我可能是错的,但我认为使用@Value和Spel不会截断逗号分隔列表中的空格。列表

foobar=a, b, c

将作为字符串列表读入

"a", " b", " c"

在大多数情况下,你可能不会想要这些空间!

表达方式

@Value("#{'${foobar}'.trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}")
private List<String> foobarList;

会给你一个字符串列表:

"a", "b", "c".

正则表达式删除逗号之前和之后的所有空格。不会删除值内的空格。所以

foobar = AA, B B, CCC

应该导致价值观

"AA", "B B", "CCC".

1
投票

考虑使用Commons配置。它具有内置功能,可以将属性文件中的条目分解为数组/列表。与SpEL和@Value合作应该给你想要的东西


根据要求,这里是你需要的(没有真正尝试过代码,可能有一些错字,请耐心等待):

在Apache Commons Configuration中,有PropertiesConfiguration。它支持将分隔字符串转换为数组/列表的功能。

例如,如果您有一个属性文件

#Foo.properties
foo=bar1, bar2, bar3

使用以下代码:

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

会给你一个字符串数组["bar1", "bar2", "bar3"]

要与Spring一起使用,请在您的应用程序上下文xml中使用:

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

在你的春豆中有这个:

public class SomeBean {

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

我相信这应该有效:P


0
投票

如果使用属性占位符,则ser1702544示例将成为

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

使用占位符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> 

0
投票

我认为抓取数组和剥离空格更简单:

@Value("#{'${my.array}'.replace(' ', '').split(',')}")
private List<String> array;

78
投票

从Spring 3.0开始,您可以添加一行

<bean id="conversionService" 
    class="org.springframework.context.support.ConversionServiceFactoryBean" />

到你的applicationContext.xml(或你配置的东西)。正如Dmitry Chornyi在评论中指出的那样,基于Java的配置如下所示:

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

这将激活支持将String转换为Collection类型的新配置服务。如果您不激活此配置服务,Spring会将其旧版属性编辑器作为配置服务,这些服务不支持此类转换。

转换为其他类型的集合也是有效的:

@Value("${my.list.of.ints}")
private List<Integer> myList

会像一条线一样工作

 my.list.of.ints= 1, 2, 3, 4

那里没有空白问题,ConversionServiceFactoryBean负责处理它。

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#core-convert-Spring-config

在Spring应用程序中,通常为每个Spring容器(或ApplicationContext)配置一个ConversionService实例。那个ConversionService将被Spring选中,然后在框架需要执行类型转换时使用。 [...]如果没有向Spring注册ConversionService,则使用基于PropertyEditor的原始系统。


29
投票

通过在.properties文件中指定my.list.of.strings=ABC,CDE,EFG并使用

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

您可以获取字符串数组。使用CollectionUtils.addAll(myList, myString),您可以获得字符串列表。


23
投票

如果您正在阅读本文并且您正在使用Spring Boot,则此功能还有1个选项

通常逗号分隔列表对于真实世界的用例非常笨拙(如果你想在你的配置中使用逗号,有时甚至不可行):

[email protected],[email protected],[email protected],.....

使用Spring Boot,您可以像这样编写它(索引从0开始):

email.sendTo[0][email protected]
email.sendTo[1][email protected]
email.sendTo[2][email protected]

并使用它像这样:

@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

19
投票

你有没有考虑过@Autowireding构造函数或者一个二传手和String.split()ing在体内?

class MyClass {
    private List<String> myList;

    @Autowired
    public MyClass(@Value("${my.list.of.strings}") final String strs) {
        myList = Arrays.asList(strs.split(","));
    }

    //or

    @Autowired
    public void setMyList(@Value("${my.list.of.strings}") final String strs) {
        myList = Arrays.asList(strs.split(","));
    }
}

我倾向于选择以其中一种方式进行自动装配以增强代码的可测试性。


7
投票

以上所有答案都是正确的。但是你可以在一行中实现这一点。请尝试以下声明,您将在字符串列表中获得所有逗号分隔值。

private @Value("#{T(java.util.Arrays).asList(projectProperties['my.list.of.strings'])}") List<String> myList;

此外,您还需要在xml配置中定义以下行。

<util:properties id="projectProperties" location="/project.properties"/>

只需替换属性文件的路径和文件名即可。你很高兴。 :)

希望这对你有所帮助。干杯。


4
投票

如果您使用的是最新的Spring框架版本(我认为是Spring 3.1+),那么您不需要在SpringEL中使用那些字符串拆分的东西,

只需在Spring的Configuration类(带有带Configuration的注释的类)中添加PropertySourcesPlaceholderConfigurer和DefaultConversionService,例如,

@Configuration
public class AppConfiguration {

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

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

在你的班上

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

并在属性文件中

list=A,B,C,D,E

如果没有DefaultConversionService,只能在将值注入字段时将逗号分隔的String转换为String数组,但DefaultConversionService会为您做一些方便的魔术,并将这些添加到Collection,Array等中。(如果你是的话,请检查实现)想了解更多信息)

有了这两个,它甚至可以处理所有冗余空格,包括换行符,因此您无需添加额外的逻辑来修剪它们。


3
投票

如果您使用的是Spring Boot 2,它将按原样运行,无需任何其他配置。

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

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

2
投票

你可以用这样的注释做到这一点

 @Value("#{T(java.util.Arrays).asList('${my.list.of.strings:a,b,c}')}") 
    private List<String> mylist;

这里将从属性文件中挑选my.list.of.strings,如果不存在,那么将使用默认值a,b,c

在你的属性文件中,你可以有这样的东西

my.list.of.strings = d,E,F

© www.soinside.com 2019 - 2024. All rights reserved.