¿Tiene acceso al archivo de propiedades de forma programática con Spring?

Usamos el siguiente código para inyectar Spring beans con propiedades de un archivo de propiedades.

      

¿Hay alguna manera de que podamos acceder a las propiedades mediante progtwigción? Estoy intentando hacer un código sin dependency injection. Entonces me gustaría tener un código como este:

 PropertyPlaceholderConfigurer props = new PropertyPlaceholderConfigurer(); props.load("classpath:/my.properties"); props.get("path"); 

¿Qué hay de PropertiesLoaderUtils ?

 Resource resource = new ClassPathResource("/my.properties"); Properties props = PropertiesLoaderUtils.loadProperties(resource); 

CRÉDITO : Acceso programático a propiedades en Spring sin volver a leer el archivo de propiedades

He encontrado una buena implementación para acceder a las propiedades programáticamente en spring sin tener que volver a cargar las mismas propiedades que la spring ya ha cargado. [Además, no es necesario codificar la ubicación del archivo de propiedad en la fuente]

Con estos cambios, el código se ve más limpio y más fácil de mantener.

El concepto es muy simple. Simplemente extienda el marcador de posición de propiedad predeterminado de spring (PropertyPlaceholderConfigurer) y capture las propiedades que carga en la variable local

 public class SpringPropertiesUtil extends PropertyPlaceholderConfigurer { private static Map propertiesMap; // Default as in PropertyPlaceholderConfigurer private int springSystemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK; @Override public void setSystemPropertiesMode(int systemPropertiesMode) { super.setSystemPropertiesMode(systemPropertiesMode); springSystemPropertiesMode = systemPropertiesMode; } @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); propertiesMap = new HashMap(); for (Object key : props.keySet()) { String keyStr = key.toString(); String valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode); propertiesMap.put(keyStr, valueStr); } } public static String getProperty(String name) { return propertiesMap.get(name).toString(); } } 

Ejemplo de uso

 SpringPropertiesUtil.getProperty("myProperty") 

Cambios de configuración de spring

     classpath:myproperties.properties    

Espero que esto ayude a resolver los problemas que tienes

Si todo lo que quiere hacer es acceder al valor del marcador de posición desde el código, está la anotación @Value :

 @Value("${settings.some.property}") String someValue; 

Para acceder a marcadores de posición Desde SPEL use esta syntax:

 #('${settings.some.property}') 

Para exponer la configuración a las vistas que tienen SPEL desactivado, se puede usar este truco:

 package com.my.app; import java.util.Collection; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.stereotype.Component; @Component public class PropertyPlaceholderExposer implements Map, BeanFactoryAware { ConfigurableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = (ConfigurableBeanFactory) beanFactory; } protected String resolveProperty(String name) { String rv = beanFactory.resolveEmbeddedValue("${" + name + "}"); return rv; } @Override public String get(Object key) { return resolveProperty(key.toString()); } @Override public boolean containsKey(Object key) { try { resolveProperty(key.toString()); return true; } catch(Exception e) { return false; } } @Override public boolean isEmpty() { return false; } @Override public Set keySet() { throw new UnsupportedOperationException(); } @Override public Set> entrySet() { throw new UnsupportedOperationException(); } @Override public Collection values() { throw new UnsupportedOperationException(); } @Override public int size() { throw new UnsupportedOperationException(); } @Override public boolean containsValue(Object value) { throw new UnsupportedOperationException(); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public String put(String key, String value) { throw new UnsupportedOperationException(); } @Override public String remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map t) { throw new UnsupportedOperationException(); } } 

Y luego use el exposer para exponer propiedades a una vista:

           

Luego a la vista, use las propiedades expuestas de esta manera:

 ${config['settings.some.property']} 

Esta solución tiene la ventaja de que puede confiar en la implementación de marcador de posición estándar inyectada por el contexto: etiqueta de marcador de propiedad.

Ahora, como nota final, si realmente necesita capturar todas las propiedades de marcador de posición y sus valores, debe canalizarlos a través de StringValueResolver para asegurarse de que los marcadores de posición funcionan dentro de los valores de propiedad como se esperaba. El siguiente código hará eso.

 package com.my.app; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.util.StringValueResolver; public class AppConfig extends PropertyPlaceholderConfigurer implements Map { Map props = new HashMap(); @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { this.props.clear(); for (Entry e: props.entrySet()) this.props.put(e.getKey().toString(), e.getValue().toString()); super.processProperties(beanFactory, props); } @Override protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) { super.doProcessProperties(beanFactoryToProcess, valueResolver); for(Entry e: props.entrySet()) e.setValue(valueResolver.resolveStringValue(e.getValue())); } // Implement map interface to access stored properties @Override public Set keySet() { return props.keySet(); } @Override public Set> entrySet() { return props.entrySet(); } @Override public Collection values() { return props.values(); } @Override public int size() { return props.size(); } @Override public boolean isEmpty() { return props.isEmpty(); } @Override public boolean containsValue(Object value) { return props.containsValue(value); } @Override public boolean containsKey(Object key) { return props.containsKey(key); } @Override public String get(Object key) { return props.get(key); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public String put(String key, String value) { throw new UnsupportedOperationException(); } @Override public String remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map t) { throw new UnsupportedOperationException(); } } 

He hecho esto y ha funcionado.

 Properties props = PropertiesLoaderUtils.loadAllProperties("my.properties"); PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer(); props2.setProperties(props); 

Eso debería funcionar.

También puede usar las utilidades de spring o cargar propiedades a través de PropertiesFactoryBean.

  

o:

    

Luego puede recogerlos en su aplicación con:

 @Resource(name = "myProps") private Properties myProps; 

y además use estas propiedades en su configuración:

  

Esto también está en los documentos: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xsd-config-body-schemas-util-properties

Crea una clase como abajo

  package com.tmghealth.common.util; import java.util.Properties; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @Configuration @PropertySource(value = { "classpath:/spring/server-urls.properties" }) public class PropertiesReader extends PropertyPlaceholderConfigurer { @Override protected void processProperties( ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); } } 

Entonces, donde quiera que quiera acceder a un uso de la propiedad

  @Autowired private Environment environment; and getters and setters then access using environment.getProperty(envName + ".letter.fdi.letterdetails.restServiceUrl"); 

– escribir getters y setters en la clase de acceso

  public Environment getEnvironment() { return environment; }`enter code here` public void setEnvironment(Environment environment) { this.environment = environment; } 

Aquí hay otra muestra.

 XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setLocation(new FileSystemResource("jdbc.properties")); cfg.postProcessBeanFactory(factory); 

Esto me ayuda:

 ApplicationContextUtils.getApplicationContext().getEnvironment() 

Esto resolverá cualquier propiedad anidada.

 public class Environment extends PropertyPlaceholderConfigurer { /** * Map that hold all the properties. */ private Map propertiesMap; /** * Iterate through all the Property keys and build a Map, resolve all the nested values before building the map. */ @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); propertiesMap = new HashMap(); for (Object key : props.keySet()) { String keyStr = key.toString(); String valueStr = beanFactory.resolveEmbeddedValue(placeholderPrefix + keyStr.trim() + DEFAULT_PLACEHOLDER_SUFFIX); propertiesMap.put(keyStr, valueStr); } } /** * This method gets the String value for a given String key for the property files. * * @param name - Key for which the value needs to be retrieved. * @return Value */ public String getProperty(String name) { return propertiesMap.get(name).toString(); } 

Esta publicación también explica cómo acceder a las propiedades: http://maciej-miklas.blogspot.de/2013/07/spring-31-programmatic-access-to.html

Puede acceder a las propiedades cargadas por el marcador de propiedad de spring sobre dicho bean de spring:

 @Named public class PropertiesAccessor { private final AbstractBeanFactory beanFactory; private final Map cache = new ConcurrentHashMap<>(); @Inject protected PropertiesAccessor(AbstractBeanFactory beanFactory) { this.beanFactory = beanFactory; } public String getProperty(String key) { if(cache.containsKey(key)){ return cache.get(key); } String foundProp = null; try { foundProp = beanFactory.resolveEmbeddedValue("${" + key.trim() + "}"); cache.put(key,foundProp); } catch (IllegalArgumentException ex) { // ok - property was not found } return foundProp; } } 

Como usted sabe, las versiones más nuevas de Spring no usan PropertyPlaceholderConfigurer y ahora usan otra construcción de pesadilla llamada PropertySourcesPlaceholderConfigurer. Si está tratando de obtener propiedades resueltas del código y desea que el equipo de Spring nos haya dado la posibilidad de hacerlo hace mucho tiempo, ¡vote esta publicación! … Porque así es como lo haces de la nueva manera:

Subclase PropertySourcesPlaceholderConfigurer:

 public class SpringPropertyExposer extends PropertySourcesPlaceholderConfigurer { private ConfigurableListableBeanFactory factory; /** * Save off the bean factory so we can use it later to resolve properties */ @Override protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, final ConfigurablePropertyResolver propertyResolver) throws BeansException { super.processProperties(beanFactoryToProcess, propertyResolver); if (beanFactoryToProcess.hasEmbeddedValueResolver()) { logger.debug("Value resolver exists."); factory = beanFactoryToProcess; } else { logger.error("No existing embedded value resolver."); } } public String getProperty(String name) { Object propertyValue = factory.resolveEmbeddedValue(this.placeholderPrefix + name + this.placeholderSuffix); return propertyValue.toString(); } } 

Para usarlo, asegúrese de usar su subclase en su @Configuration y guarde una referencia para usarla más adelante.

 @Configuration @ComponentScan public class PropertiesConfig { public static SpringPropertyExposer commonEnvConfig; @Bean(name="commonConfig") public static PropertySourcesPlaceholderConfigurer commonConfig() throws IOException { commonEnvConfig = new SpringPropertyExposer(); //This is a subclass of the return type. PropertiesFactoryBean commonConfig = new PropertiesFactoryBean(); commonConfig.setLocation(new ClassPathResource("META-INF/spring/config.properties")); try { commonConfig.afterPropertiesSet(); } catch (IOException e) { e.printStackTrace(); throw e; } commonEnvConfig.setProperties(commonConfig.getObject()); return commonEnvConfig; } } 

Uso:

 Object value = PropertiesConfig.commonEnvConfig.getProperty("key.subkey"); 
 create .properties file in classpath of your project and add path configuration in xml`` 

en servlet-context.xml después de eso, puedes usar tu archivo directamente en cualquier lugar