Come leggere i valori dal file delle proprietà?


133

Sto usando la primavera. Devo leggere i valori dal file delle proprietà. Questo è il file delle proprietà interne non il file delle proprietà esterne. Il file delle proprietà può essere come di seguito.

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

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

Ho bisogno di leggere quei valori dal file delle proprietà non in modo tradizionale. Come raggiungerlo? Esiste un approccio più recente con la primavera 3.0?


7
Questo non sembra un file di proprietà .
— Raghuram,

Se si tratta di un file delle proprietà in senso Java - sì. Altrimenti si tratta di un formato file personalizzato che deve essere trattato in modo diverso (e non è possibile utilizzare le righe come valori di proprietà in Spring se non dispongono di una chiave).
— Hauke ​​Ingmar Schmidt,

3
"Non in modo tradizionale" - cosa intendi con questo?
— Hauke ​​Ingmar Schmidt,

voglio dire usando le annotazioni ... non per configurazione xml ...
— user1016403

Risposte:


196

Configura PropertyPlaceholder nel tuo contesto:

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

Quindi fai riferimento alle proprietà nei tuoi bean:

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

EDIT: aggiornato il codice per analizzare la proprietà con valori separati da virgola multipli:

my.property.name=aaa,bbb,ccc

Se ciò non funziona, è possibile definire un bean con proprietà, iniettarlo ed elaborarlo manualmente:

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

e il fagiolo:

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

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}

Ciao mrembisz, grazie per la risposta. Ho già configurato il segnaposto per leggere i valori dal file delle proprietà esterne. ma ho un file delle proprietà nella cartella delle risorse. ho bisogno di leggere e iniettare. ho bisogno di iniettare tutti i valori nella lista. Grazie!
— user1016403,

Modificato come suggerito da @Ethan. Grazie per l'aggiornamento, non ho potuto accettare la modifica originale, era già troppo tardi.
— mrembisz,

2
Per il caso in cui avete a che fare con i valori separati da virgole forse prendere in considerazione ciò che viene qui proposto utilizzando EL: stackoverflow.com/questions/12576156/...
— arcseldon

2
Come usiamo aaa? È @Value(${aaa}) private String aaa;allora che possiamo System.out.println(aaa)???????

2
@ user75782131 Più precisamente @Value("${aaa}"), attenzione alle citazioni. E sì, puoi stamparlo tranne che nel costruttore perché il costruttore viene eseguito prima dell'iniezione dei valori.
— mrembisz,

48

Esistono vari modi per ottenere lo stesso. Di seguito sono riportati alcuni modi comunemente usati in primavera-

  1. Utilizzo di PropertyPlaceholderConfigurer

  2. Utilizzando PropertySource

  3. Utilizzo di ResourceBundleMessageSource

  4. Utilizzando PropertiesFactoryBean

    e molti altri........................

Supponendo che ds.typesia la chiave nel file delle proprietà.


utilizzando PropertyPlaceholderConfigurer

Registrati PropertyPlaceholderConfigurerbean-

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

o

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

o

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

Dopo la registrazione PropertySourcesPlaceholderConfigurer, è possibile accedere al valore-

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

utilizzando PropertySource

Nell'ultima versione di primavera non c'è bisogno di registrarsi PropertyPlaceHolderConfigurercon @PropertySource, ho trovato un buon collegamento per capire versione compatibility-

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

utilizzando ResourceBundleMessageSource

Registrati Bean-

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

Valore di accesso

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

o

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

utilizzando PropertiesFactoryBean

Registrati Bean-

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

Installa Wire Properties nella tua classe-

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}

Per utilizzare un PropertySourcesPlaceholderConfigurer è necessario impostare normalmente una posizione o una risorsa, altrimenti non è possibile accedere a un file delle proprietà. Ad esempio, è possibile utilizzare ClassPathResource generalProperties = new ClassPathResource ("general.properties");
— M46

43

Nella classe di configurazione

@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;
   }
}

In questo esempio, useresti semplicemente un diverso app.propertiestest di produzione vs. In altre parole, parte del processo di implementazione consisterebbe nel sostituire app.propertiesi valori di produzione?
— Kevin Meredith,

1
@KevinMeredith sì, è possibile, basta dividere la configurazione di primavera da Profilo annotazione stackoverflow.com/questions/12691812/...
— mokshino

@KevinMeredith usiamo una cartella fuori da deploy war: come c: \ apps \ sys_name \ conf \ app.properties. Il processo di distribuzione viene semplificato e meno soggetto a errori.
— jpfreire,

27

Ecco un'altra risposta che mi è stata di grande aiuto anche per capire come ha funzionato: http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

tutti i bean BeanFactoryPostProcessor devono essere dichiarati con un modificatore statico

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

Non è necessario registrare esplicitamente PropertySourcesPlaceholderConfigurerBean con@PropertySource

@ dubey-theHarcourtians quale versione di Spring (core) usi? se stai usando Spring Boot non hai nemmeno bisogno del @PropertySourcetutto.
— Michael Técourt,

11

Se è necessario leggere manualmente un file delle proprietà senza utilizzare @Value.

Grazie per la pagina ben scritta di Lokesh Gupta: Blog

inserisci qui la descrizione dell'immagine

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;
    }
}

Grazie, funziona per il mio caso. Devo leggere le proprietà dalla funzione statica.
— Trieu Nguyen,


4

Un altro modo è utilizzare un ResourceBundle . Fondamentalmente ottieni il bundle usando il suo nome senza ".properties"

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

E recuperi qualsiasi valore usando questo:

private final String prop = resource.getString("propName");

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>

aggiungi qualche spiegazione
— HaveNoDisplayName

utilizzando il contenitore principale non è possibile accedere al file delle proprietà delle risorse esterne, quindi è necessario utilizzare il contenitore j2ee come ApplicationContext e utilizzare la convalida a livello di bean come xmlns, xmlns: util, xsi: schemaLocation, xmlns: xsi
— Sangram Badi


0

Volevo una classe di utilità che non è gestita dalla primavera, quindi niente annotazioni di primavera come @Component, @Configurationecc. Ma volevo che la classe leggesseapplication.properties

Sono riuscito a farlo funzionare facendo in modo che la classe fosse a conoscenza del contesto di primavera, quindi ne sia consapevole Environmente quindi environment.getProperty()funzioni come previsto.

Per essere esplicito, ho:

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 (vedi Spring ottenere ApplicationContext corrente )

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);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.