2010-05-22 2 views
1

Я хочу построить ApplicationSetting для моего приложения. ApplicationSetting может быть сохранен в файле свойств или в таблице базы данных. Настройки сохраняются в парах ключ-значение. Например.Как построить мою собственную настройку приложения

ftp.host = blade 
ftp.username = dummy 
ftp.pass = pass 
content.row_pagination = 20 
content.title = How to train your dragon. 

Я разработал его следующим образом: настройки

приложений читателя:

interface IApplicationSettingReader { 
    Map read(); 
} 

DatabaseApplicationSettingReader implements IApplicationSettingReader { 
    dao appSettingDao; 

    Map read() { 
     List<AppSettingEntity> listEntity = appSettingsDao.findAll(); 
     Map<String, String> map = new HaspMap<String, String>(); 
     foreach (AppSettingEntity entity : listEntity) { 
      map.put(entity.getConfigName(), entity.getConfigValue()); 
     } 

     return new AppSettings(map); 
    } 
} 

DatabaseApplicationSettingReader implements IApplicationSettingReader { 
    dao appSettingDao; 

    Map read() { 
     //read from some properties file 
     return new AppSettings(map); 
    } 
} 

настройки приложений класса:

AppSettings { 
private static AppSettings instance = new AppSettings(); 
private Map map; 

private AppSettings() { 
} 



public static AppSettings getInstance() { 
    if (instance == null) { 
     throw new RuntimeException("Object not configure yet"); 
    } 

    return instance; 
} 

public static configure(IApplicationSettingReader reader) { 
    this.map = reader.read(); 

} 

public String getFtpSetting(String param) { 
    return map.get("ftp." + param); 
} 

public String getContentSetting(String param) { 
    return map.get("content." + param); 
} 

}

испытаний Класс:

AppSettingsTest { 
    IApplicationSettingReader reader; 

    @Before 
    public void setUp() throws Exception { 
     reader = new DatabaseApplicationSettingReader(); 
    } 

    @Test 
    public void getContentSetting_should_get_content_title() { 
     AppSettings.configure(reader); 

     Instance settings = AppSettings.getInstance(); 
     String title = settings.getContentSetting("title"); 
     assertNotNull(title); 
     Sysout(title); 
    } 

} 

Мои вопросы:

  1. Вы можете высказать свое мнение о моем коде, там что-то не так ?????

  2. настроить мое приложение настройки один раз, в то время запуска приложения, настроить установку приложений с соответствующим считывателем (DbReader или PropertiesReader), я делаю это синглтон, потому что приложение только один экземпляр ApplicationSettngs. Проблема в том, что когда какой-либо пользователь редактирует базу данных или файл непосредственно в базе данных или файле, я не могу получить измененные значения. Теперь я хочу реализовать что-то вроде ApplicationSettingChangeListener. Поэтому, если данные будут изменены, я обновлю настройки своего приложения. Есть ли у вас какие-либо предложения, как это можно реализовать?

+1

Вы видели jakarta commons config? Он поддерживает настройку чтения из многих источников, включая свойства и db. http://commons.apache.org/configuration/. В том же пространстве также находится jfig - http: // jfig.sourceforge.net/ – mdma

+0

Как узнать, изменился ли файл настроек? Файл/база данных не скажет вам, были ли они изменены на диске. Вам необходимо будет реализовать механизм автоматической проверки изменений этих файлов конфигурации на диске через определенные промежутки времени самостоятельно. (например, время модификации, токен, последние обновленные записи и т. д.) – futureelite7

+0

@mdma. Я никогда этого не пробую, я проверю. могу я задать вам вопрос? изменилось ли время поддержки поддержки библиотеки конфигурации? @ будущееelite7, да. файл или база данных не сообщают мне, что данные были изменены. основанный на вашем предположении, я могу создать приложение потока, которое проверяет конфигурацию периодической. по вашему мнению, как долго проходит интервал? поэтому я могу получить новую конфигурацию, если я получу доступ к моему приложению? по мне, я должен проверять это каждый раз, является ли это эффективным? –

ответ

0

Я не проверял ваш код, но, похоже, проблема параллелизма. Карта является поточно-опасной (HashMap), поэтому, если вы ее мутируете через config() и имеете другую карту доступа к потокам, у вас есть проблема.

Хотя вы можете использовать ConcurrentHashMap вместо HashMap, пакетная операция на ConcurrentHashMap не является атомарной. Это означает, что, если вы его используете, вы увидите измененную конфигурацию «на полпути». Это не может быть хорошо в зависимости от вашего приложения.

Таким образом, решение этого заключается в том, чтобы использовать эту функцию:

private volatile ImmutableMap map; 

public config(){ 
    ImmutableMap newMap = createNewMap(); 
    this.map = newMap; 
} 

Это изменит ваши конфиги атомарно (без промежуточного состояния не видно).

Что касается обновления вашей конфигурации на лету, log4j делает это, используя фоновый поток, который контролирует конфигурационный файл. Конечно, вы могли бы контролировать таблицу db, периодически опросив ее.

В этом случае ваш класс Config будет иметь предпочтительно ScheduledExecutor с задачей, которая будет периодически отслеживать файлы/db и вызывать config().

0

Ответ на вопрос # 2 - использовать поток и периодически проверять, был ли файл изменен или просто повторно инициализировать ваши настройки содержимым файла.

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