web-dev-qa-db-ja.com

アノテーションを使用してSpring 4でプロパティファイルを再ロードするにはどうすればよいですか?

いくつかのプロパティファイルを使用して、他のユーザーが編集したコンテンツ(サイトへのリンクなど)を取得する単純なアプリケーションがあります。

プロパティをロードするクラスは次のようになります。

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

プロパティファイルの一部:

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

これは問題なく機能しますが、プロパティファイルに変更を加えた場合は、アプリをリロードして変更を視覚化する必要があります。

場所をクラスパスではなくディスクに移動した場合、これを定期的または手動で再ロードできますか?変更時にこれが自動的に行われるのは望ましくありません。これが行われる/更新されるタイミングを制御したいからです。

15

これはごちそうです。 Java 7、Apache commons logging、Apache commons lang(v2.6)、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);
    }
}

そしてそれをテストします:

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

Test.propertiesを変更したときの出力は次のようになります(test.propsの元の内容はkey = valueでしたが、後でプログラムの実行中にkey = value1に変更されました)。

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

公式のSpring FrameworkリファレンスドキュメントRefreshable beans を検討することもできます[〜 #〜] dsl [〜#〜]これはGroovyと同じです。

10
Mikus111

新しいプロパティをリロードするには、PropertyPlaceholderConfigurerをオーバーライドする必要があります

プロパティを含むprocessPropertiesをロード可能にするには、StringValueResolverメソッドを書き直す必要があります。これは私のコードです

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

これがproperties-config.xml。これらのプロパティはすべて、プロトタイプBeanとして実行時に再ロードできます。

<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

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