Semblable à cette question: http://forum.springsource.org/showthread.php?111992-Loading-a-list-from-properties-file-using-Value-annotation (pour lequel il n'y a pas de réponse)
Je veux avoir une liste de valeurs dans un fichier .properties, par exemple:
my.list.of.strings=ABC,CDE,EFG
Et pour le charger directement dans ma classe, à savoir:
@Value("${my.list.of.strings}")
private List<String> myList;
Si j'ai bien compris, vous pouvez le faire dans le fichier de configuration printanier et le charger comme référence de bean (corrigez-moi si je me trompe), c'est-à-dire
<bean name="list">
<list>
<value>ABC</value>
<value>CDE</value>
<value>EFG</value>
</list>
</bean>
Mais y a-t-il un moyen de le faire? Vous utilisez un fichier .properties? ps: Je voudrais le faire sans code personnalisé si possible.
Utilisation de Spring EL:
@Value("#{'${my.list.of.strings}'.split(',')}")
private List<String> myList;
En supposant que votre fichier de propriétés est chargé correctement avec les éléments suivants:
my.list.of.strings=ABC,CDE,EFG
Depuis le printemps 3.0, vous pouvez ajouter une ligne comme
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean" />
à votre applicationContext.xml
(ou à l'endroit où vous configurez les choses) .. Comme Dmitry Chornyi le souligne dans un commentaire, la configuration basée sur Java ressemble à ceci:
@Bean public ConversionService conversionService() {
return new DefaultConversionService();
}
Cela active le nouveau service de configuration qui prend en charge la conversion de String
en Collection
types . Si vous n'activez pas ce service de configuration, Spring utilise ses éditeurs de propriétés hérités en tant que services de configuration qui ne prennent pas en charge ce type de conversion.
La conversion en collections d’autres types fonctionne également:
@Value("${my.list.of.ints}")
private List<Integer> myList
travaillera avec une ligne comme
my.list.of.ints= 1, 2, 3, 4
Aucun problème d’espace, la ConversionServiceFactoryBean
en prend soin.
Dans une application Spring, vous configurez généralement une instance ConversionService par conteneur Spring (ou ApplicationContext). Ce service de conversion sera récupéré par Spring, puis utilisé chaque fois qu'une conversion de type doit être effectuée par la structure . [...] Si aucun service de conversion n'est enregistré auprès de Spring, le système d'origine PropertyEditor est utilisé.
En spécifiant le my.list.of.strings=ABC,CDE,EFG
dans le fichier .properties et en utilisant
@Value("${my.list.of.strings}")
private String[] myString;
Vous pouvez obtenir les tableaux de chaînes. Et en utilisant CollectionUtils.addAll(myList, myString)
, vous pouvez obtenir la liste des chaînes.
Avez-vous envisagé @Autowired
ing le constructeur ou un setter et String.split()
ing dans le corps?
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(","));
}
}
J'ai tendance à préférer effectuer l'auto-recrutement d'une de ces manières pour améliorer la testabilité de mon code.
Si vous lisez ceci et que vous utilisez Spring Boot , vous avez 1 option supplémentaire pour cette fonctionnalité
Généralement, les listes séparées par des virgules sont très maladroites dans le cas d'utilisation réel (Et parfois même impossible, si vous voulez utiliser des virgules dans votre configuration):
[email protected],[email protected],[email protected],.....
Avec Spring Boot , vous pouvez l’écrire de la manière suivante (l’index commence à 0):
email.sendTo[0][email protected]
email.sendTo[1][email protected]
email.sendTo[2][email protected]
Et utilisez-le comme ceci:
@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
Toutes les réponses ci-dessus sont correctes. Mais vous pouvez y parvenir en une seule ligne . Essayez la déclaration suivante et vous obtiendrez toutes les valeurs séparées par des virgules dans une liste de chaînes.
private @Value("#{T(Java.util.Arrays).asList(projectProperties['my.list.of.strings'])}") List<String> myList;
Et vous devez également définir la ligne suivante dans votre configuration XML.
<util:properties id="projectProperties" location="/project.properties"/>
remplacez simplement le chemin et le nom de votre fichier de propriétés. Et vous êtes prêt à partir. :)
J'espère que cela vous aide. À votre santé.
Si vous utilisez la dernière version du framework Spring (Spring 3.1+, je crois), vous n'avez pas besoin de ces fonctions de scission de chaîne dans SpringEL,
Ajoutez simplement PropertySourcesPlaceholderConfigurer et DefaultConversionService dans la classe Configuration de votre ressort (celle avec la configuration annotée avec Configuration), par exemple,
@Configuration
public class AppConfiguration {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean public ConversionService conversionService() {
return new DefaultConversionService();
}
}
et dans ta classe
@Value("${list}")
private List<String> list;
et dans le fichier de propriétés
list=A,B,C,D,E
Sans DefaultConversionService, vous ne pouvez utiliser une chaîne séparée dans une matrice que lorsque vous injectez la valeur dans votre champ, mais DefaultConversionService effectue quelques opérations magiques pratiques et les ajoutera à Collection, Array, etc. (vérifiez l'implémentation aime en savoir plus à ce sujet)
Avec ces deux logiciels, il gère même tous les espaces blancs redondants, y compris newline. Vous n'avez donc pas besoin d'ajouter de logique pour les découper.
vous pouvez le faire avec des annotations comme celle-ci
@Value("#{T(Java.util.Arrays).asList('${my.list.of.strings:a,b,c}')}")
private List<String> mylist;
ici my.list.of.strings sera choisi dans le fichier de propriétés, s'il n'est pas présent, les valeurs par défaut a, b, c seront utilisées
et dans votre fichier de propriétés, vous pouvez avoir quelque chose comme ça
my.list.of.strings = d, e, f
Si vous utilisez Spring Boot 2, cela fonctionne tel quel, sans configuration supplémentaire.
my.list.of.strings=ABC,CDE,EFG
@Value("${my.list.of.strings}")
private List<String> myList;
Pensez à utiliser la configuration commune. Il a une fonctionnalité intégrée pour casser une entrée dans un fichier de propriétés en tableau/liste. Combiner avec SpEL et @Value devrait donner ce que vous voulez
Comme demandé, voici ce dont vous avez besoin (Je n'ai pas vraiment essayé le code, vous avez peut-être quelques typo, merci de le supporter avec moi):
Dans Apache Commons Configuration, il y a PropertiesConfiguration. Il prend en charge la fonctionnalité de conversion de chaîne délimitée en tableau/liste.
Par exemple, si vous avez un fichier de propriétés
#Foo.properties
foo=bar1, bar2, bar3
Avec le code ci-dessous:
PropertiesConfiguration config = new PropertiesConfiguration("Foo.properties");
String[] values = config.getStringArray("foo");
vous donnera un tableau de chaînes de ["bar1", "bar2", "bar3"]
Pour utiliser avec Spring, insérez ceci dans le contexte de votre application xml:
<bean id="fooConfig" class="org.Apache.commons.configuration.PropertiesConfiguration">
<constructor-arg type="Java.lang.String" value="classpath:/Foo.properties"/>
</bean>
et avoir ceci dans votre haricot de printemps:
public class SomeBean {
@Value("fooConfig.getStringArray('foo')")
private String[] fooArray;
}
Je crois que cela devrait fonctionner: P
Attention aux espaces dans les valeurs. Je peux me tromper, mais je pense que les espaces de la liste séparée par des virgules ne sont pas tronqués avec @Value et Spel. La liste
foobar=a, b, c
serait lu comme une liste de chaînes
"a", " b", " c"
Dans la plupart des cas, vous ne voudriez probablement pas les espaces!
L'expression
@Value("#{'${foobar}'.trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}")
private List<String> foobarList;
vous donnerait une liste de chaînes:
"a", "b", "c".
L'expression régulière supprime tous les espaces juste avant et juste après une virgule. Les espaces à l'intérieur des valeurs ne sont pas supprimés. Alors
foobar = AA, B B, CCC
devrait aboutir à des valeurs
"AA", "B B", "CCC".
Je pense que ceci est plus simple pour récupérer le tableau et supprimer des espaces:
@Value("#{'${my.array}'.replace(' ', '').split(',')}")
private List<String> array;
si vous utilisez des espaces réservés de propriété, ser1702544 par exemple deviendrait
@Value("#{myConfigProperties['myproperty'].trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}")
Avec espace réservé 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>