it-swarm.com.de

Lesen einer Liste aus der Eigenschaftendatei und Laden mit Federkommentar @Value

Ähnlich dieser Frage: http://forum.springsource.org/showthread.php?111992-Loading-a-list-from-properties-file-using-Value-annotation (für die keine Antwort angezeigt wird)

Ich möchte eine Liste von Werten in einer .properties-Datei haben, dh:

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

Und um es direkt in meine Klasse zu laden, dh:

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

Soweit ich weiß, besteht eine Alternative darin, sie in der Spring-Konfigurationsdatei zu haben und sie als Bean-Referenz zu laden (korrigieren Sie mich, wenn ich falsch liege), dh

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

Aber gibt es eine Möglichkeit, dies zu tun? Verwenden einer .properties-Datei? ps: Ich möchte dies, wenn möglich, ohne benutzerdefinierten Code tun.

171
JackDev

Spring EL verwenden:

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

Angenommen, Ihre Eigenschaftendatei wird mit den folgenden Anweisungen ordnungsgemäß geladen:

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

Seit dem Frühjahr 3.0 können Sie eine Zeile gerne hinzufügen

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

zu Ihrem applicationContext.xml (oder wo Sie Dinge konfigurieren) . Wie Dmitry Chornyi in einem Kommentar darauf hinweist, sieht die Java-basierte Konfiguration folgendermaßen aus:

@Bean public ConversionService conversionService() {
    return new DefaultConversionService();
}

Dadurch wird der neue Konfigurationsdienst aktiviert, der die Konvertierung von String in Collection-Typen unterstützt ..__ Wenn Sie diesen Konfigurationsdienst nicht aktivieren, greift Spring auf seine älteren Eigenschaftseditoren als Konfigurationsdienste zurück, die diese Art der Konvertierung nicht unterstützen.

Konvertieren in Sammlungen anderer Typen auch Werke:

@Value("${my.list.of.ints}")
private List<Integer> myList

funktioniert mit einer Zeile wie

 my.list.of.ints= 1, 2, 3, 4

Keine Probleme mit Whitespace, die ConversionServiceFactoryBean kümmert sich darum.

Siehe http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#core-convert-Spring-config

In einer Spring-Anwendung konfigurieren Sie normalerweise eine ConversionService-Instanz pro Spring-Container (oder ApplicationContext). Dieser ConversionService wird von Spring abgerufen und dann immer dann verwendet, wenn eine Typumwandlung vom Framework durchgeführt werden soll . [...] Wenn kein ConversionService bei Spring registriert ist, wird das ursprüngliche PropertyEditor-basierte System verwendet.

Durch Angabe der Datei my.list.of.strings=ABC,CDE,EFG in .properties und Verwendung von 

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

Sie können die Arrays von Strings erhalten. Mit CollectionUtils.addAll(myList, myString) können Sie die Liste der Strings abrufen.

28
Crazy Developer

Haben Sie in Erwägung gezogen, @Autowireding den Konstruktor oder einen Setter und String.split()ing im Körper?

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(","));
    }
}

Ich neige dazu, mein Autowiring auf eine dieser Arten zu machen, um die Testbarkeit meines Codes zu verbessern.

18

Wenn Sie dies lesen und Spring Boot verwenden, haben Sie eine weitere Option für diese Funktion

Normalerweise sind durch Kommas getrennte Listen für den realen Anwendungsfall sehr unbeholfen. (Und manchmal sogar nicht machbar, wenn Sie in Ihrer Konfiguration Kommas verwenden möchten)

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

Mit Spring Boot können Sie es wie folgt schreiben (Index beginnt bei 0):

email.sendTo[0][email protected]
email.sendTo[1][email protected]mple.com
email.sendTo[2][email protected]

Und benutze es wie folgt:

@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
16
Ng Sek Long

Alle obigen Antworten sind richtig. Sie können dies jedoch in nur einer Zeile erreichen. Bitte versuchen Sie es mit der Deklaration, und Sie erhalten alle durch Kommas getrennten Werte in einer String-Liste.

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

Außerdem muss in Ihrer XML-Konfiguration die folgende Zeile definiert sein.

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

ersetzen Sie einfach den Pfad und den Dateinamen Ihrer Eigenschaftendatei. Und du bist gut zu gehen. :)

Hoffe das hilft dir. Prost.

7
Japan Trivedi

Wenn Sie die neueste Version des Spring-Frameworks verwenden (Spring 3.1+, glaube ich), müssen Sie diese Zeichenfolge nicht in SpringEL aufteilen.

Fügen Sie einfach PropertySourcesPlaceholderConfigurer und DefaultConversionService zur Spring-Klasse Configuration hinzu (die Klasse, die mit Configuration kommentiert wurde), z. 

@Configuration
public class AppConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean public ConversionService conversionService() {
        return new DefaultConversionService();
    }
}

und in deiner Klasse 

@Value("${list}")
private List<String> list;

und in der Eigenschaftendatei

list=A,B,C,D,E

Ohne DefaultConversionService können Sie das durch Kommas getrennte String nur dann in ein String-Array einfügen, wenn Sie den Wert in Ihr Feld einfügen. DefaultConversionService übernimmt jedoch ein paar praktische Methoden und fügt diese in Collection, Array usw. ein (überprüfen Sie die Implementierung, falls Sie dies tun würden) gerne mehr darüber wissen)

Mit diesen beiden werden sogar alle redundanten Leerzeichen einschließlich Newline behandelt, sodass Sie keine zusätzlichen Logiken hinzufügen müssen, um sie zu trimmen.

2
wonhee

sie können dies mit solchen Anmerkungen tun

 @Value("#{T(Java.util.Arrays).asList('${my.list.of.strings:a,b,c}')}") 
    private List<String> mylist;

hier werden my.list.of.strings aus der Eigenschaftendatei ausgewählt. Wenn sie nicht vorhanden ist, werden die Standardwerte a, b, c verwendet

und in Ihrer Eigenschaftendatei können Sie so etwas haben

my.list.of.strings = d, e, f

2
verma

Wenn Sie Spring Boot 2 verwenden, funktioniert es ohne weitere Konfiguration.

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

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

Erwägen Sie die Verwendung der Commons-Konfiguration. Es verfügt über eine integrierte Funktion, um einen Eintrag in der Eigenschaftendatei in Array/Liste zu unterteilen. Das Kämmen mit SpEL und @Value sollte das geben, was Sie wollen


Wie gewünscht, hier ist das, was Sie brauchen (Ich habe den Code nicht wirklich ausprobiert, vielleicht ein paar Tippfehler, bitte tragen Sie mich)

In der Apache Commons-Konfiguration gibt es PropertiesConfiguration. Es unterstützt die Funktion der Konvertierung von Trennzeichen in ein Array/eine Liste.

Zum Beispiel, wenn Sie eine Eigenschaftendatei haben

#Foo.properties
foo=bar1, bar2, bar3

Mit dem folgenden Code:

PropertiesConfiguration config = new PropertiesConfiguration("Foo.properties");
String[] values = config.getStringArray("foo");

gibt dir ein String-Array von ["bar1", "bar2", "bar3"]

Um mit Spring zu verwenden, haben Sie Folgendes in Ihrem App-Kontext-XML:

<bean id="fooConfig" class="org.Apache.commons.configuration.PropertiesConfiguration">
    <constructor-arg type="Java.lang.String" value="classpath:/Foo.properties"/>
</bean>

und habe dies in deiner Frühlingsbohne:

public class SomeBean {

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

Ich glaube, das sollte funktionieren: P

1
Adrian Shum

Vorsicht vor Leerzeichen in den Werten. Ich könnte falsch sein, aber ich denke, Leerzeichen in der durch Kommas getrennten Liste werden nicht mit @Value und Spel abgeschnitten. Die Liste

foobar=a, b, c

würde als Liste von Strings eingelesen

"a", " b", " c"

In den meisten Fällen möchten Sie wahrscheinlich keine Leerzeichen!

Der Ausdruck

@Value("#{'${foobar}'.trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}")
private List<String> foobarList;

würde Ihnen eine Liste von Zeichenketten geben:

"a", "b", "c".

Mit dem regulären Ausdruck werden alle Leerzeichen vor und nach einem Komma entfernt. Leerzeichen innerhalb der Werte werden nicht entfernt. So

foobar = AA, B B, CCC

sollte zu Werten führen

"AA", "B B", "CCC".
1
DAMungra

Ich denke, das ist einfacher, um das Array zu packen und Leerzeichen zu entfernen:

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

wenn Sie Platzhalter für Eigenschaften verwenden, wird ser1702544 zum Beispiel 

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

Mit Platzhalter 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