简体   繁体   English

如何在Spring 4中使用注释重新加载属性文件?

[英]How can I reload properties file in Spring 4 using annotations?

I have a simple application where i am using several properties-files to fetch content edited by other users (links to sites etc). 我有一个简单的应用程序,其中我使用几个属性文件来获取其他用户编辑的内容(指向网站的链接等)。

The class where i load the properties look like this: 我加载属性的类如下所示:

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

Some of the properties file: 一些属性文件:

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

This works fine, but if i make changes to the properties-file, i have to reload the app to visualise any changes made. 这可以正常工作,但是如果我对properties-file进行更改,则必须重新加载应用程序以可视化所做的任何更改。

Is it possible, if i move the location to disk instead of classpath, to reload this periodically or manually? 如果我将位置移动到磁盘而不是类路径,是否可以定期或手动重新加载? I do not want this to be done automatically on change, as i want to have control over when this is done / updated. 我不希望更改时自动完成此操作,因为我想控制何时完成/更新。

This works a treat. 这可以治疗。 Requires Java 7, Apache commons logging, Apache commons lang (v2.6) and Apache commons Configuration: 需要Java 7,Apache Commons日志记录,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);
    }
}

and test it with: 并使用以下命令进行测试:

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

Output when you change test.properties is something like this (original contents of test.props was key=value, later changed to key=value1 mid-program execution): 更改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

You could also consider Official Spring Framework Reference Documentation Refreshable beans , using a DSL like Groovy for this. 您也可以考虑使用类似Groovy的DSL来考虑《 Spring Framework官方参考文档》可 刷新bean

the PropertyPlaceholderConfigurer need to be override to reload the new Properties 必须重写PropertyPlaceholderConfigurer才能重新加载新的Properties

You need to rewrite processProperties method to make the StringValueResolver which contains the properties became to loadable. 您需要重写processProperties方法,以使包含属性的StringValueResolver变为可加载。 This is my 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;
        }
   }
}

here is the configure for properties-config.xml .all of those properties can be reload in runtime as a prototype bean. 这是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>`

Inside applicationContext.xml 内部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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Spring注释将Properties文件中的值注入到现有实例(不受Spring管理)的字段中? - How do I inject a value from Properties file to a field of an existing instance (not managed by Spring) using Spring annotations? 如何仅使用批注读取Controller中的属性文件? 春季MVC - How to read properties file in Controller using annotations only? Spring MVC 使用Spring注释读取文件属性 - Read file properties using Spring annotations 如何在Spring中使用注释应用方面? - How can I apply an aspect using annotations in Spring? 如何使用Spring和注解加载策略图? - How can i load the strategy map using spring and annotations? 如何使用条件注释覆盖 spring 中的配置(例如) - How can I override configuration in spring using conditional annotations (for example) Spring - 使用注释设置属性值而不使用属性文件 - Spring - Set property value using annotations without using properties file 如何用Spring重新加载属性? - How to reload properties with Spring? 使用注释和属性文件中定义的类型的Spring autowire? - Spring autowire using annotations and a type defined in a properties file? 如何在不运行jvm的情况下在运行时在Spring中重新加载/刷新属性? - how can I reload/refresh properties in spring at runtime without jvm restart?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM