298

我想在 .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:如果可能的话,我想在没有任何自定义代码的情况下做到这一点。

4

17 回答 17

559

使用 Spring EL:

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

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

my.list.of.strings=ABC,CDE,EFG
于 2012-09-25T09:41:10.403 回答
105

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

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

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

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

这将激活支持转换StringCollection类型的新配置服务。如果您不激活此配置服务,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 的系统。

于 2015-04-30T14:23:15.617 回答
55

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

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

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

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

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

并像这样使用它:

@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
于 2017-12-01T03:23:55.420 回答
43

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

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

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

于 2012-09-25T04:57:15.077 回答
33

如果您使用的是 Spring Boot 2,它可以按原样工作,无需任何额外配置。

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

@Value("${my.list.of.strings}")
private List<String> myList;
于 2018-12-05T18:53:59.387 回答
20

您是否考虑过在正文中@Autowired使用构造函数或设置器和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(","));
    }
}

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

于 2012-09-25T04:42:53.137 回答
10

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

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

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

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

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

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

于 2012-09-25T06:57:18.640 回答
9

如果您使用的是最新的 Spring 框架版本(我相信是 Spring 3.1+),则不需要在 SpringEL 中进行字符串拆分,

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

@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,当您将值注入字段时,您只能将逗号分隔的字符串放入字符串数组中,但是 DefaultConversionService 为您做了一些方便的魔术,并将它们添加到 Collection、Array 等中(如果您愿意,请检查实现想了解更多)

有了这两个,它甚至可以处理所有多余的空格,包括换行符,所以你不需要添加额外的逻辑来修剪它们。

于 2018-11-16T04:08:37.083 回答
6

我正在使用 Spring Boot 2.2.6

我的财产文件:

usa.big.banks= JP Morgan, Wells Fargo, Citigroup, Morgan Stanley, Goldman Sachs

我的代码:

@Value("${usa.big.banks}")
    private List<String> bigBanks;

@RequestMapping("/bigbanks")
    public String getBanks() {
        System.out.println("bigBanks = " + bigBanks);
        return bigBanks.toString();
    }

它工作正常

于 2020-04-20T06:31:34.387 回答
3

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

 @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

于 2013-09-09T20:58:38.020 回答
3

注意值中的空格。我可能是错的,但我认为逗号分隔列表中的空格不会使用@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".
于 2013-11-04T10:22:54.363 回答
2

我认为这对于抓取数组和剥离空间更简单:

@Value("#{'${my.array}'.replace(' ', '').split(',')}")
private List<String> array;
于 2018-10-02T13:40:51.570 回答
2

在我的整数列表的情况下,这是这样的:

@Value("#{${my.list.of.integers}}")
private List<Integer> listOfIntegers;

属性文件:

my.list.of.integers={100,200,300,400,999}
于 2019-10-01T09:35:38.407 回答
1

考虑使用公共配置。它具有将属性文件中的条目分解为数组/列表的内置功能。结合 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

于 2012-10-01T05:39:58.943 回答
1

我的首选方式(特别是对于字符串)是以下一种:

admin.user={'Doe, John','Headroom, Max','Mouse, Micky'}

并使用

@Value("#{${admin.user}}")
private List<String> userList;

这样,您还可以在参数中包含逗号。它也适用于套装。

于 2020-01-29T15:06:52.970 回答
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> 
于 2013-12-06T09:44:57.917 回答
0

答案

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

对逗号分隔值按预期工作。要处理 null(未指定属性时),将默认值(': '在属性名称之后)添加为空字符串,如下所示:

@Value("#{'${my.list.of.strings: }'.split(',')}")
于 2021-05-12T17:26:42.847 回答