web-dev-qa-db-ja.com

プロパティファイルからリストを読み込み、スプリングアノテーション@Valueを使って読み込む

私は、.propertiesファイルに値のリストが欲しいのです。

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

そしてそれを私のクラスに直接ロードします。

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

私が理解しているように、これを実行する代わりの方法はそれをspring configファイルに入れて、それをbean参照としてロードすることです(私が間違っているなら私を修正してください)、すなわち

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

しかし、これを行う方法はありますか? .propertiesファイルを使用しますか? ps:可能であれば、カスタムコードを使わずにこれを行います。

188
JackDev

Spring ELを使う:

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

プロパティファイルが次のように正しくロードされているとします。

my.list.of.strings=ABC,CDE,EFG
371
Wilhelm Kleu

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ベースのシステムが使用されます。

.propertiesファイルでmy.list.of.strings=ABC,CDE,EFGを指定して、

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

あなたは文字列の配列を取得することができます。そしてCollectionUtils.addAll(myList, myString)を使うと、文字列のリストを取得できます。

29
Crazy Developer

あなたがこれを読んでいて、あなたがSpring Bootを使っているなら、あなたはこの機能のためのもう一つのオプションを持っています

通常、カンマ区切りのリストは実際のユースケースでは非常に不器用です(そしてあなたの設定でカンマを使いたいのなら、時には実現不可能でさえありません):

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

Spring Bootでは、次のように書くことができます(インデックスは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
23
Ng Sek Long

@Autowiredingをコンストラクターまたはセッターと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(","));
    }
}

私は自分のコードのテスト容易性を高めるためにこれらの方法の一つで私の自動配線をすることを好む傾向があります。

18

上記のすべての答えは正しいです。しかし、あなたはたった1行でこれを達成することができます。次の宣言を試してみてください。そうすれば、すべてのコンマ区切り値がStringリストに入ります。

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

そしてまた、あなたはあなたのxml設定で次の行を定義する必要があります。

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

プロパティファイルのパスとファイル名を置き換えるだけです。そして、あなたは行ってもいいです。 :)

これがお役に立てば幸いです。乾杯。

7
Japan Trivedi

最新の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などに追加します。それについてもっと知りたい)

この2つでは、改行を含むすべての冗長な空白も処理されるため、それらをトリムするためにロジックを追加する必要はありません。

4
wonhee

Spring Boot 2を使用している場合は、追加設定なしでそのまま機能します。

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

@Value("${my.list.of.strings}")
private List<String> myList;
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

2
verma

Commons Configurationの使用を検討してください。プロパティファイルのエントリをarray/listに分割する機能が組み込まれています。 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

1
Adrian Shum

値のスペースに注意してください。間違っている可能性がありますが、コンマ区切りリストのスペースは@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".
1
DAMungra

私はこれが配列をつかみスペースを取り除くために簡単であると思います:

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

プロパティプレースホルダーを使用すると、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> 
0
cgull