web-dev-qa-db-fra.com

Comment recharger un fichier de propriétés au printemps 4 en utilisant des annotations?

J'ai une application simple où j'utilise plusieurs fichiers de propriétés pour récupérer le contenu édité par d'autres utilisateurs (liens vers des sites, etc.).

La classe où je charge les propriétés ressemble à ceci: 

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

Certains des fichiers de propriétés: 

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

Cela fonctionne bien, mais si j'apporte des modifications au fichier de propriétés, je dois recharger l'application pour visualiser toutes les modifications apportées.

Est-il possible, si je déplace l'emplacement sur le disque au lieu de classpath, de recharger cette périodiquement ou manuellement? Je ne veux pas que cela se fasse automatiquement lors du changement, car je veux avoir le contrôle sur le moment où cela est fait/mis à jour.

12

Cela fonctionne un régal. Nécessite Java 7, la journalisation des communes Apache, Apache commons lang (v2.6) et Apache commons. Configuration:

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

et le tester avec:

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

La sortie lorsque vous modifiez test.properties ressemble à quelque chose comme ceci (le contenu original de test.props était clé = valeur, puis modifié en clé = valeur1 en cours d'exécution du programme):

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

Vous pouvez également envisager la documentation Official Spring Framework Reference DocumentationBeans actualisables , en utilisant un DSL comme Groovy pour cela.

11
Mikus111

le PropertyPlaceholderConfigurer doit être remplacé pour recharger les nouvelles propriétés

Vous devez réécrire la méthode processProperties pour créer la StringValueResolver qui contient les propriétés devenues chargeable . Ceci est mon 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;
        }
   }
}

voici la configuration pour properties-config.xml. Toutes ces propriétés peuvent être rechargées au moment de l’exécution en tant que bean prototype.

<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>`
7
Nonlone

À l'intérieur de l'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
Mohit Singh