2014-10-01 9 views
5

Ich habe eine einfache Anwendung, wo ich mehrere Eigenschaften-Dateien verwende, um Inhalte von anderen Benutzern (Links zu Websites usw.) bearbeitet zu holen.Wie kann ich die Eigenschaftendatei in Spring 4 mithilfe von Anmerkungen neu laden?

Die Klasse, wo ich die Eigenschaften wie folgt aussehen laden:

@Configuration 
@PropertySource("classpath:salestipsWhitelist.properties") 
public class SalestipsWhitelist { 

@Autowired 
Environment env; 

public Environment getEnv() { 
    return env; 
} 

public void setEnv(Environment env) { 
    this.env = env; 
} 

@Bean 
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 

Einige der Eigenschaften-Datei:

UPS_MPP_M_L=True 
UPS_MPP_M_M=True 
UPS_MPP_M_MP=True 
UPS_MPP_M_S=True 

Dies funktioniert gut, aber wenn ich Änderungen an den Eigenschaften-Datei, Ich muss die App neu laden, um alle vorgenommenen Änderungen zu visualisieren.

Ist es möglich, wenn ich den Speicherort auf Datenträger statt Classpath verschiebe, um es regelmäßig oder manuell neu zu laden? Ich möchte nicht, dass dies bei Änderungen automatisch gemacht wird, da ich die Kontrolle darüber haben möchte, wann dies gemacht/aktualisiert wird.

Antwort

5

Dies funktioniert ein Vergnügen. Erfordert Java 7, Apache commons Protokollierung, Apache commons lang (v2.6) und Apache commons Konfiguration:

package corejava.reloadTest; 

import org.apache.commons.configuration.ConfigurationException; 
import org.apache.commons.configuration.PropertiesConfiguration; 
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; 

public class MyApplicationProperties { 
    private static PropertiesConfiguration configuration = null; 

    static { 
     try { 
      configuration = new PropertiesConfiguration("test.properties"); 
     } catch (ConfigurationException e) { 
      e.printStackTrace(); 
     } 
     configuration.setReloadingStrategy(new FileChangedReloadingStrategy()); 
    } 

    public static synchronized String getProperty(final String key) { 
     return (String) configuration.getProperty(key); 
    } 
} 

und testen Sie es mit:

package corejava.reloadTest; 

public class TestReloading { 
    public static void main(String[] args) { 
     while (true) { 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println(MyApplicationProperties.getProperty("key")); 
     } 
    } 
} 

Ausgabe, wenn Sie test.properties ändern ist so etwas wie diese (ursprüngliche Inhalt von test.props war Schlüssel = Wert, änderte später key = Wert1 Mitte Programmausführung):

value 
value 
value 
value 
value 
Jan 17, 2015 2:05:26 PM org.apache.commons.configuration.PropertiesConfiguration reload 
INFO: Reloading configuration. URL is file:/D:/tools/workspace /AutoReloadConfigUsingApacheCommons/resources/test.properties 
value1 
value1 
value1 

Sie auch Official Spring Framework R in Erwägung ziehen könnte eference DokumentationRefreshable beans, mit einem DSL wie Groovy dafür.

+0

was, wenn Eigenschaften in JAR-Datei? –

3

die PropertyPlaceholderConfigurer müssen Überschreibung werden die neuen Eigenschaften

Sie müssen neu geladen werden processProperties Methode neu zu schreiben, die StringValueResolver zu machen, die die Eigenschaften enthält wurde ladbar. Dies ist mein Code

import java.io.IOException; 
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.util.PropertyPlaceholderHelper; 
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; 
import org.springframework.util.StringValueResolver; 


public class ReloadablePropertyPlaceholderConfigurer 
            extends PropertyPlaceholderConfigurer { 

    private ReloadablePlaceholderResolvingStringValueResolver reloadableValueResolver; 


    public void reloadProperties() throws IOException { 
     Properties props = mergeProperties(); 
     this.reloadableValueResolver.refreshProperties(props); 
    } 


    @Override 
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) 
      throws BeansException { 
     this.reloadableValueResolver = new ReloadablePlaceholderResolvingStringValueResolver(props); 
     StringValueResolver valueResolver = this.reloadableValueResolver; 
     this.doProcessProperties(beanFactoryToProcess, valueResolver); 
    } 


    private class ReloadablePlaceholderResolvingStringValueResolver 
      implements StringValueResolver { 

     private final PropertyPlaceholderHelper helper; 
     private final ReloadablePropertyPlaceholderConfigurerResolver resolver; 

     public ReloadablePlaceholderResolvingStringValueResolver(Properties props) { 
      this.helper = new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders); 
      this.resolver = new ReloadablePropertyPlaceholderConfigurerResolver(props); 
     } 

     @Override 
     public String resolveStringValue(String strVal) throws BeansException { 
      String value = this.helper.replacePlaceholders(strVal, this.resolver); 
      return (value.equals(nullValue) ? null : value); 
     } 

     private void refreshProperties(Properties props){ 
      this.resolver.setProps(props); 
     } 
    } 

    private class ReloadablePropertyPlaceholderConfigurerResolver 
      implements PlaceholderResolver { 

     private Properties props; 
     private ReloadablePropertyPlaceholderConfigurerResolver(Properties props) { 
      this.props = props; 
     } 

     @Override 
     public String resolvePlaceholder(String placeholderName) { 
      return ReloadablePropertyPlaceholderConfigurer.this.resolvePlaceholder(placeholderName, props, SYSTEM_PROPERTIES_MODE_FALLBACK); 
     } 

     public void setProps(Properties props) { 
      this.props = props; 
     } 
    } 
} 

hier ist der configure für properties-config.xml .all dieser Eigenschaften kann im laufenden Betrieb als Prototyp Bohne neu geladen werden.

<bean id="propertyConfigurer" class="com.cn21.mail189.analysis.commons.expand.ReloadablePropertyPlaceholderConfigurer"> 
    <property name="ignoreUnresolvablePlaceholders" value="true" /> 
    <property name="locations"> 
     <list> 
      <!-- database config --> 
      <value>classpath:spring/dbconfig.properties</value> 
      <!-- app config --> 
      <value>classpath:spring/app.properties</value> 
      <!-- some other config --> 
      <value>classpath:xxxx.properties</value> 
     </list> 
    </property> 
</bean>` 
+0

Willkommen bei SO. Es hilft, wenn Sie Code hinzufügen können, um die Antwort anzuzeigen. –

+0

in 'processProperties' übergeben wir' StringValueResolver' in 'doProcessProperties', die in banfactory gespeichert werden. Default 'PlaceholderResolvingStringValueResolver' in' PlaceholderConfigurerSupport' Klasse enthält den 'PropertyPlaceholderConfigurerResolver', der die Eigenschaften in final attritube behält, wenn er in' getContext' platziert wird. Wir müssen ihn umschreiben. – Nonlone

+0

Wie können wir diese Änderungen in einer vordefinierten Bean widerspiegeln? – Feng

0

Innen applicationContext.xml

<bean id="beanId" class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"> 
    <property name="refreshDelay" value="30000" /> <!-- 30 seconds --> 
</bean> 
<bean id="reloadableProperties" class="org.apache.commons.configuration.PropertiesConfiguration"> 
    <constructor-arg value="file:/web/${weblogic.Domain}/${weblogic.Name}/${app.Name}/reloadable_cfg/Reloadable.properties"/> 
    <property name="reloadingStrategy" ref="propertiesReloadingStrategy"/> 
</bean> 
+0

Wie können wir diese Eigenschaften für eine vordefinierte Bean wiedergeben? – Feng

Verwandte Themen