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

Jac*_*Dev 212 java spring spring-properties

与此问题类似:http://forum.springsource.org/showthread.php?111992-Loading-a-list-from-properties-file-using-Value-annotation(对此没有回复)

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

my.list.of.strings=ABC,CDE,EFG
Run Code Online (Sandbox Code Playgroud)

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

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

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

<bean name="list">
 <list>
  <value>ABC</value>
  <value>CDE</value>
  <value>EFG</value>
 </list>
</bean>
Run Code Online (Sandbox Code Playgroud)

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

Wil*_*leu 405

使用Spring EL:

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

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

my.list.of.strings=ABC,CDE,EFG
Run Code Online (Sandbox Code Playgroud)

  • 空属性`my.list.of.strings =`怎么样?我希望这样的功能重新清空空列表,这里它将是一个项目(空字符串),不是吗? (13认同)
  • 如果您需要修剪空格,请使用正则表达式进行拆分参数.. 类似`@Value("#{'${my.list.of.strings}'.split(',\\s*')}") ` (6认同)
  • 另请注意,建议的解决方案不会进行修剪,因此像`item1,item2,item3`这样的值可能会给出您并不真正期望的结果(提示:空格). (5认同)

Cle*_*aar 84

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

<bean id="conversionService" 
    class="org.springframework.context.support.ConversionServiceFactoryBean" />
Run Code Online (Sandbox Code Playgroud)

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

@Bean public ConversionService conversionService() {
    return new DefaultConversionService();
}
Run Code Online (Sandbox Code Playgroud)

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

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

@Value("${my.list.of.ints}")
private List<Integer> myList
Run Code Online (Sandbox Code Playgroud)

会像一条线一样工作

 my.list.of.ints= 1, 2, 3, 4
Run Code Online (Sandbox Code Playgroud)

没有空白问题,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的原始系统.

  • Java配置:@Bean public ConversionService conversionService(){return new DefaultConversionService(); } (6认同)
  • 这对我有用,试图从`.properties`文件加载一个浮点列表. (2认同)
  • 避免在每个表达式中使用`split()`重复自己,它也正确地处理一个空列表而不是给你`[null] (2认同)

Muk*_*mar 32

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

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

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


Ng *_*ong 31

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

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

email.sendTo=somebody@example.com,somebody2@example.com,somebody3@example.com,.....
Run Code Online (Sandbox Code Playgroud)

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

email.sendTo[0]=somebody@example.com
email.sendTo[1]=somebody2@example.com
email.sendTo[2]=somebody3@example.com
Run Code Online (Sandbox Code Playgroud)

并使用它像这样:

@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
Run Code Online (Sandbox Code Playgroud)


nic*_*ild 19

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

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(","));
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Ank*_*kit 11

我正在使用 Spring Boot 2.2.6

我的财产档案:

usa.big.banks= JP Morgan, Wells Fargo, Citigroup, Morgan Stanley, Goldman Sachs
Run Code Online (Sandbox Code Playgroud)

我的代码:

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

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

效果很好


Jap*_*edi 8

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

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

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

<util:properties id="projectProperties" location="/project.properties"/>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这对我有用,但我不得不这样写注释:`@Value("#{T(java.util.Arrays).asList('${my.list.of.strings}')}")` (2认同)

Bie*_*vid 8

如果您使用的是Spring Boot 2,则无需任何其他配置即可直接使用。

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

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

  • 是的,它也对我有用:我正在使用 Spring Boot 2.2.6 (2认同)

won*_*hee 6

如果您使用的是最新的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在你班上

@Value("${list}")
private List<String> list;
Run Code Online (Sandbox Code Playgroud)

并在属性文件中

list=A,B,C,D,E
Run Code Online (Sandbox Code Playgroud)

如果没有DefaultConversionService,则在将值注入字段时只能将逗号分隔的String放入String数组中,但是DefaultConversionService会为您提供一些方便的魔术,并将它们添加到Collection,Array等中。想了解更多)

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


Sam*_*isa 6

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

admin.user={'Doe, John','Headroom, Max','Mouse, Micky'}
Run Code Online (Sandbox Code Playgroud)

并使用

@Value("#{${admin.user}}")
private List<String> userList;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您还可以在参数中包含逗号。它也适用于集合。