![](/img/trans.png)
[英]How to build my own ConfirmAjaxButton in Apache Wicket?
[英]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);
}
}
我的問題是:
您能對我的代碼發表意見嗎,有什么問題嗎?
我配置了一次應用程序設置,在應用程序啟動時,我使用適當的讀取器( DbReader
或PropertiesReader
)配置了應用程序設置,因為應用程序只有一個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.