Comment lire les valeurs du fichier de propriétés?

133

J'utilise le ressort. J'ai besoin de lire les valeurs du fichier de propriétés. Il s'agit du fichier de propriétés interne et non du fichier de propriétés externes. Le fichier de propriétés peut être comme ci-dessous.

some.properties ---file name. values are below.

abc = abc
def = dsd
ghi = weds
jil = sdd

J'ai besoin de lire ces valeurs à partir du fichier de propriétés pas de manière traditionnelle. Comment y parvenir? Existe-t-il une dernière approche avec Spring 3.0?

utilisateur1016403
la source
7
Cela ne ressemble pas à un fichier de propriétés .
Raghuram
S'il s'agit d'un fichier de propriétés au sens Java - oui. Sinon, c'est un format de fichier personnalisé qui doit être traité différemment (et vous ne pouvez pas simplement utiliser les lignes comme valeurs de propriété dans Spring si elles n'ont pas de clé).
Hauke ​​Ingmar Schmidt
3
"Pas de manière traditionnelle" - qu'entendez-vous par là?
Hauke ​​Ingmar Schmidt
je veux dire en utilisant des annotations ... pas par configuration xml ...
user1016403

Réponses:

196

Configurez PropertyPlaceholder dans votre contexte:

<context:property-placeholder location="classpath*:my.properties"/>

Ensuite, vous vous référez aux propriétés de vos beans:

@Component
class MyClass {
  @Value("${my.property.name}")
  private String[] myValues;
}

EDIT: mise à jour du code pour analyser la propriété avec plusieurs valeurs séparées par des virgules:

my.property.name=aaa,bbb,ccc

Si cela ne fonctionne pas, vous pouvez définir un bean avec des propriétés, l'injecter et le traiter manuellement:

<bean id="myProperties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath*:my.properties</value>
    </list>
  </property>
</bean>

et le haricot:

@Component
class MyClass {
  @Resource(name="myProperties")
  private Properties myProperties;

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}
mrembisz
la source
Salut mrembisz, Merci pour votre réponse. J'ai déjà configuré propert-placeholder pour lire les valeurs du fichier de propriétés externes. mais j'ai un fichier de propriétés dans le dossier des ressources. j'ai besoin de lire et d'injecter. J'ai besoin d'injecter toutes les valeurs dans la liste. Merci!
user1016403
Modifié comme suggéré par @Ethan. Merci pour la mise à jour, impossible d'accepter la modification d'origine, il était déjà trop tard.
mrembisz
2
Dans le cas où vous avez affaire à des valeurs séparées par des virgules, considérez peut-être ce qui est proposé ici en utilisant EL: stackoverflow.com/questions/12576156/…
arcseldon
2
Comment utilisons-nous aaa? Est-ce @Value(${aaa}) private String aaa;alors que nous pouvons System.out.println(aaa)???????
2
@ user75782131 Plus précisément @Value("${aaa}"), faites attention aux citations. Et oui, vous pouvez l'imprimer sauf pas dans le constructeur car le constructeur est exécuté avant que les valeurs ne soient injectées.
mrembisz
48

Il existe différentes manières d'atteindre la même chose. Vous trouverez ci-dessous quelques méthodes couramment utilisées au printemps.

  1. Utilisation de PropertyPlaceholderConfigurer

  2. Utilisation de PropertySource

  3. Utilisation de ResourceBundleMessageSource

  4. Utilisation de PropertiesFactoryBean

    et beaucoup plus........................

En supposant que ds.typec'est la clé dans votre fichier de propriété.


En utilisant PropertyPlaceholderConfigurer

Enregistrer PropertyPlaceholderConfigurerbean-

<context:property-placeholder location="classpath:path/filename.properties"/>

ou

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations" value="classpath:path/filename.properties" ></property>
</bean>

ou

@Configuration
public class SampleConfig {
 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
  //set locations as well.
 }
}

Après vous être enregistré PropertySourcesPlaceholderConfigurer, vous pouvez accéder à la valeur-

@Value("${ds.type}")private String attr; 

En utilisant PropertySource

Dans la dernière version de printemps , vous n'avez pas besoin de vous inscrire PropertyPlaceHolderConfigureravec @PropertySource, j'ai trouvé un bon lien pour comprendre la version compatibility-

@PropertySource("classpath:path/filename.properties")
@Component
public class BeanTester {
    @Autowired Environment environment; 
    public void execute() {
        String attr = this.environment.getProperty("ds.type");
    }
}

En utilisant ResourceBundleMessageSource

Enregistrer Bean-

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basenames">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

Valeur d'accès-

((ApplicationContext)context).getMessage("ds.type", null, null);

ou

@Component
public class BeanTester {
    @Autowired MessageSource messageSource; 
    public void execute() {
        String attr = this.messageSource.getMessage("ds.type", null, null);
    }
}

En utilisant PropertiesFactoryBean

Enregistrer Bean-

<bean id="properties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

Wire Properties dans votre classe

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}
Communauté
la source
Pour utiliser un PropertySourcesPlaceholderConfigurer, vous devez normalement définir un emplacement ou une ressource, sinon vous ne pourriez pas accéder à un fichier de propriétés. Vous pouvez utiliser par exemple ClassPathResource generalProperties = new ClassPathResource ("general.properties");
M46
43

En classe de configuration

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
   @Autowired
   Environment env;

   @Bean
   public TestBean testBean() {
       TestBean testBean = new TestBean();
       testBean.setName(env.getProperty("testbean.name"));
       return testBean;
   }
}
mokshino
la source
Dans cet exemple, utiliseriez-vous simplement un autre app.propertiesen production v. Testing? En d'autres termes, une partie de votre processus de déploiement consisterait-elle à remplacer app.propertiespar des valeurs de production?
Kevin Meredith
1
@KevinMeredith oui, vous pouvez, il suffit de diviser votre configuration de ressort par l'annotation de profil stackoverflow.com/questions/12691812/…
mokshino
@KevinMeredith nous utilisons un dossier en dehors de deploy war: comme c: \ apps \ nom_sys \ conf \ app.properties. Le processus de déploiement est simplifié et moins sujet aux erreurs.
jpfreire
27

Voici une réponse supplémentaire qui m'a également été d'une grande aide pour comprendre son fonctionnement: http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

tous les beans BeanFactoryPostProcessor doivent être déclarés avec un modificateur statique

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {
 @Value("${test.prop}")
 private String attr;
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }

 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}
Michael Técourt
la source
Pas besoin d'enregistrer explicitement PropertySourcesPlaceholderConfigurerBean avec@PropertySource
@ dubey-theHarcourtians quelle version Spring (principale) utilisez-vous? si vous utilisez Spring Boot, vous n'en avez même pas besoin @PropertySource.
Michael Técourt
11

Si vous devez lire manuellement un fichier de propriétés sans utiliser @Value.

Merci pour la page bien écrite de Lokesh Gupta: Blog

entrez la description de l'image ici

package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;


public class Utils {

    private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());

    public static Properties fetchProperties(){
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return properties;
    }
}
John
la source
Merci, cela fonctionne pour mon cas. J'ai besoin de lire les propriétés de la fonction statique.
Trieu Nguyen
6

Vous devez placer un bean PropertyPlaceholderConfigurer dans le contexte de votre application et définir sa propriété d'emplacement.

Voir les détails ici: http://www.zparacha.com/how-to-read-properties-file-in-spring/

Vous devrez peut-être modifier un peu votre fichier de propriété pour que cela fonctionne.

J'espère que ça aide.

instanceOfObject
la source
4

Une autre façon consiste à utiliser un ResourceBundle . En gros, vous obtenez le bundle en utilisant son nom sans le '.properties'

private static final ResourceBundle resource = ResourceBundle.getBundle("config");

Et vous récupérez n'importe quelle valeur en utilisant ceci:

private final String prop = resource.getString("propName");
Miluna
la source
0
 [project structure]: http://i.stack.imgur.com/RAGX3.jpg
-------------------------------
    package beans;

        import java.util.Properties;
        import java.util.Set;

        public class PropertiesBeans {

            private Properties properties;

            public void setProperties(Properties properties) {
                this.properties = properties;
            }

            public void getProperty(){
                Set keys = properties.keySet();
                for (Object key : keys) {
                    System.out.println(key+" : "+properties.getProperty(key.toString()));
                }
            }

        }
    ----------------------------

        package beans;

        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

        public class Test {

            public static void main(String[] args) {
                // TODO Auto-generated method stub
                ApplicationContext ap = new ClassPathXmlApplicationContext("resource/spring.xml");
                PropertiesBeans p = (PropertiesBeans)ap.getBean("p");
                p.getProperty();
            }

        }
    ----------------------------

 - driver.properties

    Driver = com.mysql.jdbc.Driver
    url = jdbc:mysql://localhost:3306/test
    username = root
    password = root
    ----------------------------



     <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:util="http://www.springframework.org/schema/util"
               xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

            <bean id="p" class="beans.PropertiesBeans">
                <property name="properties">
                    <util:properties location="classpath:resource/driver.properties"/>
                </property>
            </bean>

        </beans>
Sangram Badi
la source
ajouter une explication
HaveNoDisplayName
en utilisant le conteneur principal, vous ne pouvez pas accéder au fichier de propriétés des ressources extérieures, vous devez donc utiliser le conteneur j2ee comme ApplicationContext, et vous devez utiliser la validation au niveau des beans comme xmlns, xmlns: util, xsi: schemaLocation, xmlns: xsi
Sangram Badi
0

Je voulais une classe utilitaire qui n'est pas gérée par spring, donc pas d'annotations de printemps comme @Component, @Configurationetc. Mais je voulais que la classe lise à partir deapplication.properties

J'ai réussi à le faire fonctionner en faisant en sorte que la classe soit consciente du contexte Spring, donc en soit consciente Environment, et environment.getProperty()fonctionne donc comme prévu.

Pour être explicite, j'ai:

application.properties

mypath=somestring

Utils.java

import org.springframework.core.env.Environment;

// No spring annotations here
public class Utils {
    public String execute(String cmd) {
        // Making the class Spring context aware
        ApplicationContextProvider appContext = new ApplicationContextProvider();
        Environment env = appContext.getApplicationContext().getEnvironment();

        // env.getProperty() works!!!
        System.out.println(env.getProperty("mypath")) 
    }
}

ApplicationContextProvider.java (voir Spring obtenir le ApplicationContext actuel )

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext CONTEXT;

    public ApplicationContext getApplicationContext() {
        return CONTEXT;
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        CONTEXT = context;
    }

    public static Object getBean(String beanName) {
        return CONTEXT.getBean(beanName);
    }
}
Sida Zhou
la source