Accéder au fichier de propriétés par programmation avec Spring?

Nous utilisons le code ci-dessous pour injecter des haricots Spring avec des propriétés d’un fichier de propriétés.

      

Est-il possible d’accéder aux propriétés par programmation? J’essaie de faire du code sans dependency injection. J’aimerais donc avoir un code comme celui-ci:

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

Que diriez-vous de PropertiesLoaderUtils ?

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

CREDIT : Accès par programme aux propriétés au spring sans relecture du fichier de propriétés

J’ai trouvé une bonne implémentation d’accéder aux propriétés par programmation au spring sans recharger les mêmes propriétés que Spring a déjà chargées. [En outre, il n’est pas nécessaire de coder en dur l’emplacement du fichier de propriétés dans la source]

Avec ces modifications, le code semble plus propre et plus facile à entretenir.

le concept est assez simple. Il suffit de prolonger l’espace réservé par défaut de la propriété Spring (PropertyPlaceholderConfigurer) et de capturer les propriétés qu’il charge dans la variable locale

 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()) { Ssortingng keyStr = key.toSsortingng(); Ssortingng valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode); propertiesMap.put(keyStr, valueStr); } } public static Ssortingng getProperty(Ssortingng name) { return propertiesMap.get(name).toSsortingng(); } } 

Exemple d’utilisation

 SpringPropertiesUtil.getProperty("myProperty") 

Changements de configuration du spring

     classpath:myproperties.properties    

J’espère que cela aide à résoudre les problèmes que vous avez

Si tout ce que vous voulez faire est d’accéder à la valeur d’espace réservé à partir du code, il y a l’annotation @Value :

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

Pour accéder aux espaces réservés De SPEL, utilisez cette syntaxe:

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

Pour exposer la configuration à des vues dont SPEL est désactivé, on peut utiliser cette astuce:

 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 Ssortingng resolveProperty(Ssortingng name) { Ssortingng rv = beanFactory.resolveEmbeddedValue("${" + name + "}"); return rv; } @Override public Ssortingng get(Object key) { return resolveProperty(key.toSsortingng()); } @Override public boolean containsKey(Object key) { try { resolveProperty(key.toSsortingng()); 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 Ssortingng put(Ssortingng key, Ssortingng value) { throw new UnsupportedOperationException(); } @Override public Ssortingng remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map t) { throw new UnsupportedOperationException(); } } 

Et puis utilisez l’exposeur pour exposer les propriétés à une vue:

           

Ensuite, utilisez les propriétés exposées comme ceci:

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

Cette solution présente l’avantage de pouvoir compter sur une implémentation d’espaces réservés standard injectée par le tag context: property-placeholder.

Maintenant, pour finir, si vous avez vraiment besoin de capturer toutes les propriétés de l’espace réservé et leurs valeurs, vous devez les canaliser via SsortingngValueResolver pour vous assurer que les espaces réservés fonctionnent comme prévu dans les valeurs de propriété. Le code suivant fera cela.

 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.SsortingngValueResolver; 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().toSsortingng(), e.getValue().toSsortingng()); super.processProperties(beanFactory, props); } @Override protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, SsortingngValueResolver valueResolver) { super.doProcessProperties(beanFactoryToProcess, valueResolver); for(Entry e: props.entrySet()) e.setValue(valueResolver.resolveSsortingngValue(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 Ssortingng get(Object key) { return props.get(key); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public Ssortingng put(Ssortingng key, Ssortingng value) { throw new UnsupportedOperationException(); } @Override public Ssortingng remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map t) { throw new UnsupportedOperationException(); } } 

Je l’ai fait et cela a fonctionné.

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

Cela devrait fonctionner.

Vous pouvez également utiliser les utilitaires de spring ou les propriétés de chargement via PropertiesFactoryBean.

  

ou:

    

Vous pouvez ensuite les récupérer dans votre application avec:

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

et en outre utiliser ces propriétés dans votre configuration:

  

Ceci est également dans les docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xsd-config-body-schemas-util-properties

Créez une classe comme ci-dessous

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

Ensuite, où que vous souhaitiez accéder à une utilisation de propriété

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

– écrire des getters et des setters dans la classe accesseur

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

Voici un autre échantillon.

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

Cela m’aide:

 ApplicationContextUtils.getApplicationContext().getEnvironment() 

Cela résoudra toutes les propriétés nestedes.

 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()) { Ssortingng keyStr = key.toSsortingng(); Ssortingng valueStr = beanFactory.resolveEmbeddedValue(placeholderPrefix + keyStr.sortingm() + DEFAULT_PLACEHOLDER_SUFFIX); propertiesMap.put(keyStr, valueStr); } } /** * This method gets the Ssortingng value for a given Ssortingng key for the property files. * * @param name - Key for which the value needs to be resortingeved. * @return Value */ public Ssortingng getProperty(Ssortingng name) { return propertiesMap.get(name).toSsortingng(); } 

Cet article explique également comment accéder aux propriétés: http://maciej-miklas.blogspot.de/2013/07/spring-31-programmatic-access-to.html

Vous pouvez accéder aux propriétés chargées par la propriété-placeholder de spring sur ces haricots 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; } } 

Comme vous le savez, les versions plus récentes de Spring n’utilisent pas le PropertyPlaceholderConfigurer et utilisent désormais une autre construction cauchemardesque appelée PropertySourcesPlaceholderConfigurer. Si vous essayez d’obtenir des propriétés résolues à partir du code, et que vous souhaitez que l’équipe de Spring nous donne le moyen de le faire depuis longtemps, alors votez pour cette publication! … Parce que c’est comme ça que tu fais la nouvelle façon:

Sous-classe 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 Ssortingng getProperty(Ssortingng name) { Object propertyValue = factory.resolveEmbeddedValue(this.placeholderPrefix + name + this.placeholderSuffix); return propertyValue.toSsortingng(); } } 

Pour l’utiliser, veillez à utiliser votre sous-classe dans votre configuration @ et à enregistrer une référence à celle-ci pour une utilisation ultérieure.

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

Usage:

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

dans servlet-context.xml après cela vous pouvez directement utiliser votre fichier partout