¿Cómo leer valores del archivo de propiedades?

133

Estoy usando la primavera Necesito leer valores del archivo de propiedades. Este es un archivo de propiedades interno, no el archivo de propiedades externo. El archivo de propiedades puede ser el siguiente.

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

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

Necesito leer esos valores del archivo de propiedades no de manera tradicional. ¿Cómo lograrlo? ¿Hay algún enfoque más reciente con spring 3.0?

usuario1016403
fuente
77
Esto no se parece a un archivo de propiedades .
Raghuram
Si es un archivo de propiedades en el sentido de Java, sí. De lo contrario, es un formato de archivo personalizado que debe tratarse de manera diferente (y no puede usar las líneas como valores de propiedad en Spring si no tienen una clave).
Hauke ​​Ingmar Schmidt
3
"No en la forma tradicional", ¿qué quieres decir con esto?
Hauke ​​Ingmar Schmidt
me refiero usando annotations..not por la configuración xml ...
user1016403

Respuestas:

196

Configure PropertyPlaceholder en su contexto:

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

Luego se refieren a las propiedades en sus granos:

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

EDITAR: se actualizó el código para analizar la propiedad con varios valores separados por comas:

my.property.name=aaa,bbb,ccc

Si eso no funciona, puede definir un bean con propiedades, inyectarlo y procesarlo manualmente:

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

y el frijol:

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

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}
mrembisz
fuente
Hola mrembisz, gracias por tu respuesta. Ya configuré el marcador de posición de propiedad para leer valores del archivo de propiedades externo. pero tengo un archivo de propiedades dentro de la carpeta de recursos. Necesito leer e inyectar. Necesito inyectar todos los valores en la lista. ¡Gracias!
user1016403
Editado según lo sugerido por @Ethan. Gracias por la actualización, no se pudo aceptar la edición original, ya era demasiado tarde.
mrembisz
2
Para el caso en el que está tratando con valores separados por comas, quizás considere lo que se propone aquí utilizando EL: stackoverflow.com/questions/12576156/…
arcseldon
2
¿Cómo lo usamos aaa? ¿Es @Value(${aaa}) private String aaa;entonces que podemos System.out.println(aaa)???????
2
@ user75782131 Más precisamente @Value("${aaa}"), tenga en cuenta las citas. Y sí, puede imprimirlo excepto en el constructor porque el constructor se ejecuta antes de que se inyecten los valores.
mrembisz
48

Hay varias formas de lograr lo mismo. A continuación se presentan algunas formas comúnmente utilizadas en primavera.

  1. Uso de PropertyPlaceholderConfigurer

  2. Usando PropertySource

  3. Usando ResourceBundleMessageSource

  4. Usando PropertiesFactoryBean

    y muchos más........................

Asumir ds.typees clave en su archivo de propiedades.


Utilizando PropertyPlaceholderConfigurer

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

Después de registrarse PropertySourcesPlaceholderConfigurer, puede acceder al valor

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

Utilizando PropertySource

En la última versión de primavera que no es necesario registrar PropertyPlaceHolderConfigurercon @PropertySource, me encontré con un buen enlace para entender versión compatibility-

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

Utilizando ResourceBundleMessageSource

Registrarse 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 acceso

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

Utilizando PropertiesFactoryBean

Registrarse 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 las propiedades de Wire en su clase

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}
Comunidad
fuente
Para usar un PropertySourcesPlaceholderConfigurer, normalmente debe establecer una ubicación o recurso, de lo contrario no podría acceder a un archivo de propiedades. Puede utilizar, por ejemplo, ClassPathResource generalProperties = new ClassPathResource ("general.properties");
M46
43

En la clase de configuración

@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
fuente
En este ejemplo, ¿simplemente usaría una app.propertiesprueba diferente en producción v. En otras palabras, ¿parte de su proceso de implementación sería reemplazar app.propertiescon valores de producción?
Kevin Meredith
1
@KevinMeredith sí, puedes, simplemente divide tu configuración de resorte por la anotación de perfil stackoverflow.com/questions/12691812/…
mokshino
@KevinMeredith usamos una carpeta fuera de despliegue war: como c: \ apps \ sys_name \ conf \ app.properties. El proceso de implementación se simplifica y es menos propenso a errores.
jpfreire
27

Aquí hay una respuesta adicional que también fue de gran ayuda para entender cómo funcionaba: http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

cualquier bean BeanFactoryPostProcessor debe declararse con un 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
fuente
No es necesario registrar explícitamente PropertySourcesPlaceholderConfigurerBean con@PropertySource
@ dubey-theHarcourtians, ¿qué versión de Spring (core) usas? Si está utilizando Spring Boot, ni siquiera lo necesita por @PropertySourcecompleto.
Michael Técourt
11

Si necesita leer manualmente un archivo de propiedades sin usar @Value.

Gracias por la página bien escrita de Lokesh Gupta: Blog

ingrese la descripción de la imagen aquí

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;
    }
}
Juan
fuente
Gracias, funciona para mi caso. Necesito leer las propiedades de la función estática.
Trieu Nguyen
6

Debe colocar un bean PropertyPlaceholderConfigurer en el contexto de su aplicación y establecer su propiedad de ubicación.

Ver detalles aquí: http://www.zparacha.com/how-to-read-properties-file-in-spring/

Es posible que deba modificar un poco su archivo de propiedades para que esto funcione.

Espero eso ayude.

instanceOfObject
fuente
4

Otra forma es usar un ResourceBundle . Básicamente, obtienes el paquete usando su nombre sin las '.properties'

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

Y recuperas cualquier valor usando esto:

private final String prop = resource.getString("propName");
Miluna
fuente
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
fuente
agregue alguna explicación
HaveNoDisplayName
usando el contenedor central no puede acceder al archivo de propiedades de recursos externos, por lo que debe usar el contenedor j2ee como ApplicationContext, y debe usar la validación de nivel de beans como xmlns, xmlns: util, xsi: schemaLocation, xmlns: xsi
Sangram Badi
0

Quería una clase de utilidad que no sea administrada por spring, así que no hay anotaciones de spring como @Component, @Configurationetc. Pero quería que la clase leyeraapplication.properties

Me las arreglé para que funcionara haciendo que la clase conozca el Contexto de Primavera, por lo tanto, esté al tanto Environmenty, por lo tanto, environment.getProperty()funcione como se esperaba.

Para ser explícito, tengo:

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 (vea Spring get Current ApplicationContext )

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
fuente