2013-01-02 8 views
3

Я написал класс PropertyUtils (из Интернета), который загрузит Свойствадинамической загрузки файл свойств с помощью Spring

<bean id="propertiesUtil" class="com.myApp.PropertiesUtil" > 
    <property name="locations"> 
     <list> 
      <value>classpath:myApp/myApp.properties</value>   
     </list> 
    </property> 
</bean> 

и класс PropertiesUtil как ниже

public class PropertiesUtil extends PropertyPlaceholderConfigurer { 

    private static Map<String, String> properties = new HashMap<String, String>(); 

    @Override 
    protected void loadProperties(final Properties props) throws IOException { 
     super.loadProperties(props); 
     for (final Object key : props.keySet()) { 
      properties.put((String) key, props.getProperty((String) key)); 
     } 
    } 

    public String getProperty(final String name) { 
     return properties.get(name); 
    } 

} 

Позже, я могу получить свойство, вызвав метод PropertiesUtil.getProperty().

Но теперь я хочу, чтобы изменить его немного, например, что если myApp.properties модифицируются/изменены пользователем, он должен быть загружен снова

Возможно, мне нужен класс FileWatcher

public abstract class FileWatcher extends TimerTask { 
    private long timeStamp; 
    private File file; 

    public FileWatcher(File file) { 
     this.file = file; 
     this.timeStamp = file.lastModified(); 
    } 

    @Override 
    public final void run() { 
     long timeStampNew = this.file.lastModified(); 

     if (this.timeStamp != timeStampNew) { 
      this.timeStamp = timeStampNew; 
      onChange(this.file); 
     } 
    } 

    protected abstract void onChange(File newFile); 
} 

но мой сомнения

  1. Как создать объект File, используя путь к классам: MYAPP/myApp.properties (потому что абсолютный путь не известен)
  2. Как мне вызвать/вызвать весну до загрузить/передать новые параметры myApp.properties классу PropetisUtil [в onChange method].
+0

В вашем методе loadProperties() есть ли какая-либо конкретная причина, по которой вы выполняете цикл для каждого свойства? Не можете ли вы использовать конструктор класса Properties, который принимает свойства как param? – Parvez

ответ

6

Вы можете использовать класс ReloadableResourceBundleMessageSource Spring, как показано ниже:

<?xml version="1.0" encoding="UTF-8" ?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> 

    <bean id="myProperties" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <!-- check property file(s) every 1 second --> 
     <property name="cacheSeconds" value="1"/> 
     <property name="basenames"> 
      <list> 
       <value>myApp/myApp</value> 
      </list> 
     </property> 
    </bean> 

</beans> 

И тогда вы можете вызвать MessageSource.getMessage() метод, чтобы получить значение свойства. Вот пример:

package com.example; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.MessageSource; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class MyApp { 
public static void main(String[] args) throws InterruptedException { 
     ApplicationContext ctx = new ClassPathXmlApplicationContext("myApp/MyApp.xml"); 
     MessageSource myProperties = (MessageSource) ctx.getBean("myProperties"); 
     while (true) { 
      System.out.println(myProperties.getMessage("myApp.propertyOne", null, null)); 
      Thread.sleep(1000); 
     } 
    } 
} 

Вы можете напрямую позвонить ApplicationContext.getMessage (String код, Object [] арг, локали), если вы переименовали ваш боб 'myProperties' как 'messageSource'.

Для ваших веб-приложений размещайте свои файлы свойств за пределами пути к классу вашего веб-приложения (поскольку веб-сервер может их кэшировать). Так, например, WEB-INF/CONF/myApp.properties

+0

Можете ли вы привести пример о том, как получить свойство? org.springframework.context.ApplicationContext.getMessage() этот метод не существует. – Reddy

6

Следующая поддерживает то, что вы ищете:

http://commons.apache.org/configuration/userguide/howto_filebased.html

PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties"); 
config.setReloadingStrategy(new FileChangedReloadingStrategy()); 

Это должно сделать трюк. Я не использовал его сам, но он, кажется, довольно прямолинейный.

+0

Звучит неплохо. Любой рабочий учебник? – Reddy

+0

http://commons.apache.org/configuration/userguide/howto_filebased.html это дает довольно хорошее введение. – Till

0

Может быть простым способом было бы сделать так:

<util:properties location="classpath:config.properties" id="configProperties" /> 
<context:property-placeholder properties-ref="configProperties" /> 

Таким образом, вы можете получить доступ к любой из свойств бина инъекционного/обращающегося боба с именем «configProperties». Не уверен, что это то, что вам нужно, потому что во время выполнения невозможно изменить configProperties. Но это чистый способ, и вам не нужно писать дополнительный класс.

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