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.