Чтение списка из файла свойств и загрузка с помощью spring аннотации @Value

Я хочу иметь список значений в файле .properties, а именно:

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

И загрузить это в моем классе непосредственно, то есть:

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

Как я понимаю, альтернатива для этого - поместить его в конфигурационный файл Spring и загрузить как ссылку на компонент (поправьте меня, если я ошибаюсь), т.е.

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

Но есть ли способ сделать это? используя файл .properties? PS: Я хотел бы сделать это без любого пользовательского кода, если это возможно.

Ответ 1

Использование Spring EL:

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

Предположим, что ваш файл свойств загружен правильно:

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

Ответ 2

Так как Spring 3.0, вы можете добавить строку типа

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

на ваш applicationContext.xml (или где вы настраиваете вещи). Как отмечает Дмитрий Чорний в комментарии, конфигурация на основе 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 обычно настраивается экземпляр ConversionService для контейнера Spring (или ApplicationContext). Этот ConversionService будет подхвачен Spring, а затем использоваться всякий раз, когда преобразование типа должно выполняться каркасом. [...] Если ConversionService не зарегистрирован в Spring, используется исходная система на основе PropertyEditor.

Ответ 3

Задав файл my.list.of.strings=ABC,CDE,EFG in.properties и используя

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

Вы можете получить массивы строк. И используя CollectionUtils.addAll(myList, myString), вы можете получить список строк.

Ответ 4

Если вы читаете это, и используете Spring Boot, у вас есть еще одна опция для этой функции

Обычно список, разделенный запятыми, очень неуклюжий для случая использования в реальном мире (И когда-нибудь даже не выполнимо, если вы хотите использовать запятые в своей конфигурации):

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

С Spring Загрузка вы можете записать его так (начало индекса в 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

Ответ 5

Рассматривали ли вы @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(","));
    }
}

Я предпочитаю делать свое автоувеличивание одним из этих способов, чтобы повысить возможность проверки моего кода.

Ответ 6

Все приведенные выше ответы верны. Но вы можете добиться этого только в одной строке. Попробуйте выполнить декларацию, и вы получите все значения, разделенные запятыми, в списке строк.

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

А также вы должны иметь следующую строку, определенную в вашей конфигурации xml.

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

просто замените путь и имя файла вашего файла свойств. И тебе хорошо идти.:)

Надеюсь, это поможет вам. Приветствия.

Ответ 7

Если вы используете Spring Boot 2, он работает так же, как и без дополнительной настройки.

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

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

Ответ 8

Если вы используете последнюю версию Spring Framework (Spring 3. 1+, я полагаю), вам не нужны эти строки, разделенные в SpringEL,

Просто добавьте PropertySourcesPlaceholderConfigurer и DefaultConversionService в свой класс Spring 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 вы можете использовать только String в String массив, когда вы вводите значение в свое поле, но DefaultConversionService делает несколько удобных магов для вас и добавит их в Collection, Array и т.д. (Проверьте реализацию, если вы хотел бы узнать больше об этом)

С этими двумя, он даже обрабатывает все избыточные пробелы, включая новую строку, поэтому вам не нужно добавлять дополнительные логики для их обрезки.

Ответ 9

вы можете сделать это с помощью аннотаций, подобных этому

 @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

Ответ 10

Остерегайтесь пробелов в значениях. Я мог ошибаться, но я думаю, что пробелы в списке с разделителями-запятыми не усекаются с помощью @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".

Ответ 11

Рассмотрите возможность использования 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 bean:

public class SomeBean {

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

Я считаю, что это должно работать: P

Ответ 12

если использовать заполнители свойств, тогда пример ser1702544 станет

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

С помощью 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> 

Ответ 13

Я думаю, что это проще для захвата массива и снятия пробелов:

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

Ответ 14

В моем случае список целых чисел работает так:

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

Файл объекта:

my.list.of.integers={100,200,300,400,999}