Java 如何构建我自己的应用程序设置
我想为我的应用程序构建一个应用程序设置。应用程序设置可以存储在属性文件或数据库表中。设置存储在键值对中。例如Java 如何构建我自己的应用程序设置,java,design-patterns,configuration,Java,Design Patterns,Configuration,我想为我的应用程序构建一个应用程序设置。应用程序设置可以存储在属性文件或数据库表中。设置存储在键值对中。例如 ftp.host = blade ftp.username = dummy ftp.pass = pass content.row_pagination = 20 content.title = How to train your dragon. 我的设计如下: 应用程序设置读取器: interface IApplicationSettingReader { Map r
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);
}
}
}
测试等级:
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);
}
}
我的问题是:
你能谈谈你对我的代码的看法吗,有什么问题吗
我配置了一次应用程序设置,当应用程序启动时,我使用适当的reader DbReader或PropertiesReader配置应用程序设置,我将其设置为singleton,因为应用程序只有一个ApplicationSettings实例。问题是,当一些用户将数据库或文件直接编辑到数据库或文件时,我无法获得更改的值。现在,我想实现类似ApplicationSettingChangeListener的东西。因此,如果数据发生更改,我将刷新我的应用程序设置。你对如何实现这一目标有什么建议吗
我还没有彻底检查您的代码,但似乎存在并发问题。该映射是线程不安全的HashMap,所以如果您通过config对其进行修改,并让其他线程访问该映射,则会出现问题 虽然可以使用ConcurrentHashMap代替HashMap,但ConcurrentHashMap上的批处理操作不是原子操作。这意味着,如果您使用它,您将看到一个中途修改的配置。这取决于你的应用程序 因此,解决这个问题的方法是使用:
private volatile ImmutableMap map;
public config(){
ImmutableMap newMap = createNewMap();
this.map = newMap;
}
这将自动更改配置,中间状态不可见
至于动态更新配置,log4j使用一个后台线程来监视配置文件。当然,您可以通过定期轮询来监视db表
在这种情况下,您的Config类最好有一个ScheduledExecutor,其任务将监视文件/db并定期调用Config 问题2的答案是使用线程并定期检查文件是否已更改,或者简单地用文件内容重新初始化设置。您看过雅加达公用配置吗?它支持从许多源读取配置,包括属性和数据库。在相同的空间中,也是jfig-您如何知道设置文件是否更改?文件/数据库不会告诉您它们是否已在磁盘上更改。您需要实现一种机制来自动检查磁盘上这些配置文件在特定时间间隔内的更改。e、 g.修改时间、令牌、上次更新的条目等@mdma。我从来没试过,我会检查的。我可以问你一个问题吗?配置库支持运行时是否已更改@未来精英7,是的。文件或数据库不告诉我数据已更改。根据您的建议,我可以创建线程应用程序,定期检查配置。根据你的说法,间隔多长时间?如果我访问我的应用程序,那么我可以获得新的配置?根据我的说法,我每次都必须检查它,这有效吗?我同意mdma。commons配置还支持检测配置更改。我也建议你不要使用单身汉。一般来说,单例使代码不易测试和重用。为什么我使用单例,应用程序只有一个应用程序设置,对应用程序进行多个配置是不好的。所以我用了单身汉。为什么你会说,singleton使代码不易测试和重用?谢谢
private volatile ImmutableMap map;
public config(){
ImmutableMap newMap = createNewMap();
this.map = newMap;
}