Como ler valores do arquivo de propriedades?

133

Eu estou usando a primavera. Eu preciso ler valores do arquivo de propriedades. Este é um arquivo de propriedades interno, não o arquivo de propriedades externas. O arquivo de propriedades pode ser como abaixo.

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

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

Eu preciso ler esses valores do arquivo de propriedades não da maneira tradicional. Como conseguir isso? Existe alguma abordagem mais recente com a primavera 3.0?

user1016403
fonte
7
Isso não parece um arquivo de propriedades .
Raghuram
Se é um arquivo de propriedades no sentido de Java - sim. Caso contrário, é um formato de arquivo personalizado que precisa ser tratado de forma diferente (e você não pode simplesmente usar as linhas como valores de propriedade no Spring se elas não tiverem uma chave).
Hauke ​​Ingmar Schmidt
3
"Não da maneira tradicional" - o que você quer dizer com isso?
Hauke ​​Ingmar Schmidt
i dizer com annotations..not pela configuração XML ...
user1016403

Respostas:

196

Configure o PropertyPlaceholder no seu contexto:

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

Então você se refere às propriedades em seus beans:

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

EDIT: atualizou o código para analisar a propriedade com vários valores separados por vírgula:

my.property.name=aaa,bbb,ccc

Se isso não funcionar, você pode definir um bean com propriedades, injetar e processá-lo manualmente:

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

e o feijão:

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

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}
mrembisz
fonte
Oi Mrembisz, Obrigado pela sua resposta. Eu já configurei o propert-placeholder para ler valores do arquivo de propriedades externas. mas eu tenho um arquivo de propriedades dentro da pasta de recursos. Eu preciso ler e injetar. Eu preciso injetar todos os valores na lista. Obrigado!
user1016403
Editado como sugerido por @Ethan. Obrigado pela atualização, não foi possível aceitar a edição original, já era tarde demais.
26413 mrembisz
2
Para o caso em que você está lidando com valores separados por vírgula talvez considerar o que está sendo proposto aqui usando EL: stackoverflow.com/questions/12576156/...
arcseldon
2
Como usamos aaa? É @Value(${aaa}) private String aaa;então que podemos System.out.println(aaa)???????
2
@ user75782131 Mais precisamente @Value("${aaa}"), observe as aspas. E sim, você pode imprimi-lo, exceto não no construtor, porque o construtor é executado antes dos valores serem injetados.
22414 mrembisz
48

Existem várias maneiras de conseguir o mesmo. Abaixo estão algumas maneiras comumente usadas na primavera

  1. Usando PropertyPlaceholderConfigurer

  2. Usando PropertySource

  3. Usando ResourceBundleMessageSource

  4. Usando PropertiesFactoryBean

    e muitos mais........................

Supondo que ds.typeseja a chave do seu arquivo de propriedades.


Usando PropertyPlaceholderConfigurer

Registrar 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.
 }
}

Após o registro PropertySourcesPlaceholderConfigurer, você pode acessar o valor

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

Usando PropertySource

Na última versão primavera você não precisa se registrar PropertyPlaceHolderConfigurercom @PropertySource, eu encontrei uma boa ligação para entender versão compatibility-

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

Usando ResourceBundleMessageSource

Registrar Bean-

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

Valor de acesso-

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

Usando PropertiesFactoryBean

Registrar Bean-

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

Instale as propriedades das propriedades na classe

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}
Comunidade
fonte
Para usar um PropertySourcesPlaceholderConfigurer, normalmente você deve definir um local ou recurso, caso contrário não poderá acessar um arquivo de propriedades. Você pode usar, por exemplo, ClassPathResource generalProperties = new ClassPathResource ("general.properties");
M46
43

Na classe de configuração

@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
fonte
Neste exemplo, você simplesmente usaria um diferente app.propertiesna produção v. Testing? Em outras palavras, parte do seu processo de implantação seria substituir app.propertiespelos valores de produção?
22815 Kevin Meredith
1
@KevinMeredith sim, você pode, basta dividir a sua configuração de mola por Perfil anotação stackoverflow.com/questions/12691812/...
mokshino
@ KevinMeredith, usamos uma pasta fora do deploy war: como c: \ apps \ sys_name \ conf \ app.properties. O processo de implantação é simplificado e menos propenso a erros.
Jpfreire
27

Aqui está uma resposta adicional que também foi de grande ajuda para entender como funcionava: http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

todos os beans BeanFactoryPostProcessor devem ser declarados com um modificador estático

@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
fonte
Não há necessidade de registrar explicitamente o PropertySourcesPlaceholderConfigurerBean com@PropertySource
@ dubey-theHarcourtians qual versão Spring (principal) você usa? se você estiver usando o Spring Boot, nem precisará dele @PropertySource.
Michael Técourt
11

Se você precisar ler manualmente um arquivo de propriedades sem usar o @Value.

Obrigado pela página bem escrita de Lokesh Gupta: Blog

insira a descrição da imagem aqui

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
fonte
Obrigado, funciona para o meu caso. Eu preciso ler as propriedades da função estática.
Trieu Nguyen
6

Você precisa colocar um bean PropertyPlaceholderConfigurer no contexto do aplicativo e definir sua propriedade de localização.

Veja detalhes aqui: http://www.zparacha.com/how-to-read-properties-file-in-spring/

Pode ser necessário modificar um pouco o arquivo de propriedades para que isso funcione.

Espero que ajude.

instanceOfObject
fonte
4

Outra maneira é usar um ResourceBundle . Basicamente, você obtém o pacote usando seu nome sem as '.properties'

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

E você recupera qualquer valor usando isso:

private final String prop = resource.getString("propName");
Miluna
fonte
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
fonte
adicione alguma explicação
HaveNoDisplayName
usando o contêiner principal, você não pode acessar o arquivo de propriedades de recurso externo; portanto, é necessário usar o contêiner j2ee como ApplicationContext e a validação no nível de beans como xmlns, xmlns: util, xsi: schemaLocation, xmlns: xsi
Sangram Badi
0

Eu queria uma classe de utilidade que não fosse gerenciada pela primavera, então não há anotações da primavera @Component, @Configurationetc. Mas eu queria que a classe lesseapplication.properties

Eu consegui fazê-lo funcionar, fazendo com que a classe conhecesse o Contexto Spring, portanto, está ciente Environmente, portanto, environment.getProperty()funciona conforme o esperado.

Para ser explícito, eu tenho:

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 (consulte Spring, obtenha o ApplicationContext atual )

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
fonte