簡體   English   中英

如何構建自己的應用程序設置

[英]How build my own Application Setting

我想為我的應用程序構建一個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. 我配置了一次應用程序設置,在應用程序啟動時,我使用適當的讀取器( DbReaderPropertiesReader )配置了應用程序設置,因為應用程序只有一個ApplicationSettngs實例,所以使它成為單例。 問題是,當某些用戶將數據庫或文件直接編輯為數據庫或文件時,我無法獲取更改后的值。 現在,我想實現類似ApplicationSettingChangeListener 因此,如果數據更改,我將刷新我的應用程序設置。 您對如何實現此建議有什么建議嗎?

我尚未徹底檢查您的代碼,但似乎存在並發問題。 該映射是線程不安全的(HashMap),因此,如果您通過config()對其進行了更改,並讓其他線程訪問該映射,則會出現問題。

盡管可以使用ConcurrentHashMap代替HashMap ,但對ConcurrentHashMap的批處理操作不是原子的。 這意味着,如果使用它,您將看到“半途”修改的配置。 根據您的應用程序,這可能不正確。

因此,解決方案是使用以下方法:

private volatile ImmutableMap map;

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

這將自動更改您的配置(沒有可見的中間狀態)。

至於即時更新配置,log4j使用監視配置文件的后台線程來完成。 當然,您可以監視數據庫表,而不是定期輪詢它。

在這種情況下,您的Config類最好具有一個ScheduledExecutor,其任務將監視文件/ db並定期調用config()。

問題2的答案是使用線程並定期檢查文件是否已更改,或僅使用文件內容重新初始化設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM