簡體   English   中英

從屬性文件中讀取列表並加載彈簧注釋 @Value

[英]Reading a List from properties file and load with spring annotation @Value

我想在 .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:如果可能的話,我想在沒有任何自定義代碼的情況下做到這一點。

使用 Spring EL:

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

假設您的屬性文件使用以下內容正確加載:

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

從 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 的系統。

如果您正在閱讀本文並且正在使用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

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

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

您可以獲得字符串數組。 並使用CollectionUtils.addAll(myList, myString) ,您可以獲得字符串列表。

如果您使用的是 Spring Boot 2,它會按原樣工作,無需任何額外配置。

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

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

您是否考慮過@Autowired構造函數或主體中的 setter 和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(","));
    }
}

我傾向於以其中一種方式進行自動裝配,以增強代碼的可測試性。

以上所有答案都是正確的。 但是您可以在一行中實現這一點。 請嘗試以下聲明,您將獲得字符串列表中的所有逗號分隔值。

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

而且您還需要在 xml 配置中定義以下行。

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

只需替換屬性文件的路徑和文件名。 你很高興去。 :)

希望這對你有幫助。 干杯。

如果您使用的是最新的 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 等中(如果您願意,請檢查實現想了解更多關於它)

有了這兩個,它甚至可以處理所有多余的空格,包括換行符,因此您無需添加額外的邏輯來修剪它們。

我正在使用 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();
    }

它工作正常

你可以用這樣的注釋來做到這一點

 @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

注意值中的空格。 我可能是錯的,但我認為逗號分隔列表中的空格不會使用 @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".

我認為這對於抓取數組和剝離空間更簡單:

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

在我的整數列表的情況下,它是這樣工作的:

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

屬性文件:

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

考慮使用公共配置。 它具有將屬性文件中的條目分解為數組/列表的內置功能。 結合 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

我的首選方式(特別是對於字符串)是以下一種:

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

並使用

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

這樣,您還可以在參數中包含逗號。 它也適用於集合。

如果使用屬性占位符,則 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> 

答案

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

對於逗號分隔值,按預期工作。 要處理空值(未指定屬性時),將默認值(屬性名稱后的': ' )添加為空字符串,如下所示:

@Value("#{'${my.list.of.strings: }'.split(',')}")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM