首页 文章

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

提问于
浏览
165

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

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

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

并直接加载到我的 class ,即:

@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:如果可能的话,我想用任何自定义代码执行此操作 .

13 回答

  • 0

    您是否考虑过 @Autowired 构造函数或者setter和 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(","));
        }
    }
    

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

  • 1

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

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

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

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

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

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

  • 324

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

    @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

  • 71

    注意值中的空格 . 我可能错了,但我认为逗号分隔列表中的空格不会被@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
    

    应该导致 Value 观

    "AA", "B B", "CCC".
    
  • 2

    使用Spring EL:

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

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

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

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

    只需在Spring的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等中 . (如果你是的话,请检查实现)想了解更多信息)

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

  • 18

    从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的系统 .

  • 1

    考虑使用Commons Configuration . 它具有内置功能,可以将属性文件中的条目分解为数组/列表 . 与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>
    

    在你的 Spring beans 中有这个:

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

    我相信这应该有效:P

  • 0

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

    my.list.of.strings=ABC,CDE,EFG
    
    @Value("${my.list.of.strings}")
    private List<String> myList;
    
  • 12

    如果您正在阅读此内容而您正在使用 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
    
  • 2

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

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

    如果使用属性占位符,则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>
    
  • 7

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

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

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

相关问题