2014-10-01 4 views
5

У меня есть простое приложение, в котором я использую несколько свойств-файлов для извлечения контента, отредактированного другими пользователями (ссылки на сайты и т. Д.).Как загрузить файл свойств в 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 

Это прекрасно работает, но если я внести изменения в свойства-файла, я должен перезагрузить приложение, чтобы визуализировать сделанные изменения.

Возможно ли, если я переместлю местоположение на диск вместо classpath, чтобы перезагрузить его периодически или вручную? Я не хочу, чтобы это было сделано автоматически при изменении, так как я хочу контролировать, когда это будет сделано/обновлено.

ответ

5

Это работает. Требуется 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 был ключ = значение, позже изменено на ключ = значение1 исполнение в середине программы):

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 

Вы могли бы также рассмотреть вопрос о Official Spring Framework R eference ДокументацияRefreshable beans, используя DSL как Groovy для этого.

+0

, что если свойства в банке файл? –

3

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

Добро пожаловать в SO. Это помогает, если вы можете добавить код, чтобы показать ответ. –

+0

в 'processProperties' мы передаем' StringValueResolver' в 'doProcessProperties', который будет храниться в beanfactory. По умолчанию 'PlaceholderResolvingStringValueResolver' в классе' PlaceholderConfigurerSupport' удерживает 'PropertyPlaceholderConfigurerResolver', которые сохраняют свойства в конечном attritube, когда помещают его в метод getContext', нам нужно переписать его – Nonlone

+0

Как мы можем отразить эти изменения свойств в предопределенном компоненте? – Feng

0

Внутри 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

Как мы можем отразить эти свойства в предопределенном компоненте? – Feng

Смежные вопросы